Pythonでブログの検索順位を取得するツールを作っています。
前回までに、
- キーワードでGoogle検索
- 検索結果からブログ順位を取得
- 検索キーワード一覧をExcelファイルから取得
する部分を作ってきました。
今回は、今までの機能を実行後にExcelに結果を書き出す部分を作ってみます。
ちなみに、この記事のタイトルをPython超初心者から、ただの初心者に変更してみました。
さすがに「超」初心者は脱したでしょう。
キーワード検索してExcelファイルに書き出す
キーワードでGoogle検索して、ブログの順位をExcelファイルに書き出してみます。
ソースコード
作成したソースコードです。
全部載せます。
前回までのコードと被る部分がほとんどですが、今回追加した箇所のみ抜き出したら流れが分かり辛いので。
やっていることは、
- 検索キーワード一覧をExcelから読み込む
- キーワードでGoogle検索する
- 検索順位をExcelに書き出す
です。2~3を検索キーワード分繰り返します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
import requests as web import bs4 import openpyxl as px import datetime #Excelブックオープン book = px.load_workbook('ブログ検索順位.xlsx') #シート名取得 #sheet = book.get_sheet_names() sheet = book.sheetnames #シート名表示 print(sheet) for i in range(len(sheet)): #シート数分ループ if sheet[i] == '検索ワード': word_sheet = sheet[i] #シートを設定 #ws = book.get_sheet_by_name(word_sheet) ws = book[word_sheet] if sheet[i] == '検索順位': #シートを設定 wr = book[sheet[i]] #最大行の取得 erow = ws.max_row word_list = [] #検索ワードリスト for i in range(erow): #最終行までループ #セルの値をリストに追加 word_list.append(ws.cell(row=i+1,column=1).value) #検索ワードリストの表示 print(word_list) #検索順位を書き出す列 ecol = wr.max_column now_col = ecol+1 td = datetime.date.today() #今日の日付 wr.cell(row=1,column=now_col,value=td) for ilist in range(len(word_list)): print('------------------------------------------------') #検索キーワード keyword = word_list[ilist] print('検索ワード:' + keyword) #出力シートにキーワードを書く(既にある場合はスルー) flg = 0 erow = wr.max_row #最終行 for i in range(erow): if wr.cell(row=i+1,column=1).value == keyword: flg = 1 now_row = i+1 break if flg != 1: wr.cell(row=erow+1,column=1,value=keyword) now_row = erow+1 #リクエストヘッダー headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"} #上位50件まで検索結果を取得 url = 'https://www.google.co.jp/search?hl=ja&num=50&q=' + keyword #接続 response = web.get(url, headers=headers) with open('test.html','w',encoding='utf-8') as f: f.write(response.text) #HTTPステータスコードをチェック(200以外は例外処理) response.raise_for_status() #取得したHTMLをパース soup = bs4.BeautifulSoup(response.content, 'html.parser') #検索結果のタイトルとリンクを取得 ret_link = soup.select('.r > a') title_list = [] url_list = [] for i in range(len(ret_link)): # タイトルのテキスト部分を取得 title_txt = ret_link[i].get_text() # リンクのみを取得し、余計な部分を削除する url_link = ret_link[i].get('href').replace('/url?q=','') title_list.append(title_txt) url_list.append(url_link) blog_url = "https://rikei-fufu.com" flg = 0 for i in range(len(title_list)): str_url = url_list[i] if str_url.startswith(blog_url): print('ブログが検索結果にありました') blog_no = i + 1 blog_title = title_list[i] print('順位:' + str(blog_no) + '位') print('記事:' + blog_title) flg = 1 #出力シート wr.cell(row=now_row,column=2,value=str_url) wr.cell(row=now_row,column=3,value=blog_title) wr.cell(row=now_row,column=now_col,value=blog_no) break if flg != 1: print('検索範囲内にブログはありませんでした。') book.save('ブログ検索順位.xlsx') |
追加箇所
今回新たに追加した機能を紹介します。
forループで複数の検索キーワードで検索する
検索キーワードは複数あるので、「Google検索して順位を取得する」という動作をforループで回します。
該当箇所はここ
1 2 |
for ilist in range(len(word_list)): keyword = word_list[ilist] |
(今回はforループがたくさんあるので、ループ変数を「ilist」にして混乱しないようにしました。)
日付を取得
Excelファイルに検索順位を書き出す際、日付も一緒に出力していきたいので、日付を取得してみます。
「datetime」モジュールをインポートします。(pipでインストールする必要はなかったです。標準で入っています。)
1 2 |
import datetime td = datetime.date.today() #今日の日付 |
Excelファイルに検索結果を書き出す
ここが今回の肝。
シート変数「wr」に検索結果を出力するシートを設定し、cellに行番号、列番号と書き出す値を入れます。
セルに入れる値も引数に書くのがポイント。
1 2 3 |
wr.cell(row=now_row,column=2,value=str_url) wr.cell(row=now_row,column=3,value=blog_title) wr.cell(row=now_row,column=now_col,value=blog_no) |
VBAの方が書き出し方が簡単で分かり易いな・・・と。
いちいち「row=***,columns=***」と書かなきゃいけないのが面倒くさいですね。
引数に順番に値のみ書くようにすればいいのにな。
また、Excelファイルの保存は
1 |
book.save('ブログ検索順位.xlsx') |
でできます。
ファイル名を読み込み時から変えれば新規に保存されますが、同じなら上書き保存です。
ファイル書き出し結果
上記のソースコードを実行して出力された結果は

まぁ、やりたいことはできていますね。
順位もしっかり表示できていますし。
しかし、記事タイトルに書かれた文字列が、「Baby Kumon(ベビーくもん)に2年間(24回)通った効果 | 理系夫婦の方程式https://rikei-fufu.com/2019/04/12/post-424/」というふうに、タイトルの後にURLも付いてしまっています。
また、日付も「2019-06-27」というフォーマットが気持ち悪い。
好みの見た目になるように、少し改善してみます。
見た目を改善しよう
出力結果の見た目が良くなるように改善したソースコードです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
import requests as web import bs4 import openpyxl as px import datetime #Excelブックオープン book = px.load_workbook('ブログ検索順位.xlsx') #シート名取得 #sheet = book.get_sheet_names() sheet = book.sheetnames #シート名表示 print(sheet) for i in range(len(sheet)): #シート数分ループ if sheet[i] == '検索ワード': word_sheet = sheet[i] #シートを設定 #ws = book.get_sheet_by_name(word_sheet) ws = book[word_sheet] if sheet[i] == '検索順位': #シートを設定 wr = book[sheet[i]] #最大行の取得 erow = ws.max_row word_list = [] #検索ワードリスト for i in range(erow): #最終行までループ #セルの値をリストに追加 word_list.append(ws.cell(row=i+1,column=1).value) #検索ワードリストの表示 print(word_list) #検索順位を書き出す列 i=1 while wr.cell(row=1,column=i).value != None: i=i+1 now_col = i td = datetime.date.today().strftime('%Y/%m/%d') #今日の日付 wr.cell(row=1,column=now_col,value=td) for ilist in range(len(word_list)): print('------------------------------------------------') #検索キーワード keyword = word_list[ilist] print('検索ワード:' + keyword) #出力シートにキーワードを書く(既にある場合はスルー) flg = 0 i=0 while wr.cell(row=i+1,column=1).value != None: #空白セルまでループ if wr.cell(row=i+1,column=1).value == keyword: flg = 1 now_row = i+1 break i=i+1 if flg != 1: wr.cell(row=i+1,column=1,value=keyword) now_row = i+1 print('行:' + str(now_row)) #リクエストヘッダー headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"} #上位50件まで検索結果を取得 url = 'https://www.google.co.jp/search?hl=ja&num=50&q=' + keyword #接続 response = web.get(url, headers=headers) #HTTPステータスコードをチェック(200以外は例外処理) response.raise_for_status() #取得したHTMLをパース soup = bs4.BeautifulSoup(response.content, 'html.parser') #検索結果のタイトルとリンクを取得 ret_link = soup.select('.r > a') title_list = [] url_list = [] for i in range(len(ret_link)): # タイトルのテキスト部分を取得 title_txt = ret_link[i].get_text() # リンクのみを取得し、余計な部分を削除する url_link = ret_link[i].get('href').replace('/url?q=','') title_list.append(title_txt) url_list.append(url_link) blog_url = "https://rikei-fufu.com" flg = 0 for i in range(len(title_list)): str_url = url_list[i] if str_url.startswith(blog_url): print('ブログが検索結果にありました') blog_no = i + 1 blog_title_s = title_list[i] #タイトルの後のURLは削除 cut=blog_title_s.find(blog_url) #インデックス blog_title = blog_title_s[:cut] print('順位:' + str(blog_no) + '位') print('記事:' + blog_title) flg = 1 #出力シート wr.cell(row=now_row,column=2,value=str_url) wr.cell(row=now_row,column=3,value=blog_title) wr.cell(row=now_row,column=now_col,value=blog_no) break if flg != 1: print('検索範囲内にブログはありませんでした。') wr.cell(row=now_row,column=now_col,value='×') book.save('ブログ検索順位.xlsx') |
改善点
上記コードのどこが改善点なのかをまとめます。
日付のフォーマットを指定
デフォルトだと「yyyy-mm-dd」形式で出力されてしまうので、「yyyy/mm/dd」とスラッシュで区切るようなフォーマットを指定してみます。
1 |
datetime.date.today().strftime('%Y/%m/%d') |
これでフォーマット指定できます。
記事タイトルからURLを削除
検索結果から取得した記事タイトルにURLが混じっているので、URLを削除します。
この部分を追加しました。
1 2 |
cut=blog_title_s.find(blog_url) #インデックス blog_title = blog_title_s[:cut] |
「blog_title_s」は検索結果の記事タイトル文字列、「blog_url」はブログのTOPページURLです。
「find」で文字列の中からブログURLが始まる場所を探します。
「blog_title_s[:cut]」で、ブログURLより前の部分までを取り出して、違う文字列変数に格納しています。
これを「スライシング」というようです。
参考: Pythonの文字列を抽出する方法まとめ
これで文字列から不要な部分を削除できます。
最終行・最終列の取得方法の変更
プログラムを何回も実行していると、Excelの最終行・最終列の取得結果がおかしくなり、うまくファイルに書き出せないときがありました。
セルの値を消していても、「空白ではないセル」として判断されちゃっているよう。
なので、「max_row」といった関数は使わず、while文で空白セルまでループして最終行を求めるようにしました。
最終列の取得
1 2 3 |
i=1 while wr.cell(row=1,column=i).value != None: i=i+1 |
最終行の取得
1 2 3 |
i=0 while wr.cell(row=i+1,column=1).value != None: #空白セルまでループ i=i+1 |
cell(row,column)==None
が空白セルとなります。
このやり方だと上手く最終行・最終列の取得ができるようになります。
ファイル書き出し結果
改善してみたコードを実行してみると

このようなExcelファイルができました。
うん、良くなりました。
日付も「yyyy/mm/dd」形式ですし、記事タイトルもURLが消えました。
(「|理系夫婦の方程式」の部分も消した方がスッキリするな・・・後でやろう)
あえて検索50位以内に入らなそうなキーワードも追加してみましたが、きちんと「×」が出力できています。(D9セル)
基本的な機能はこれで備わったかな。
あとは、やはりデスクトップアプリとして使えるようにGUIで操作できるようにしたいのと、グラフも作れるようにしたい。
理想の検索順位取得ツールとなるように、これからもチャレンジしていきます。
んじゃ、また~
コメント