本記事では、PythonでのWebスクレイピングを行い、Google検索の上位サイトのH1、H2、H3タグを抽出するソースコードをご紹介します。
想定読者
・ブログで競合サイトを簡単に分析したい。Pythonも少しわかる。
・Pythonを勉強していて、Webスクレイピングのやり方を参考にしたい。
・Webスクレイピングをやろうとして、つまづいている。
Webスクレイピングの実行環境(Python)
・Linux
・Python 3.7.6
・requests: 2.24.0
・bs4: 4.8.2
・pandas: 1.1.2
・numpy: 1.18.1
WebスクレイピングでGoogle検索の上位サイトのH1、H2、H3タグを抽出するコード(Python)
実際のPythonのコードは、次のようになります。
下のコードでは、検索ワードを「ブログ初心者」としております。
import requests
import bs4
import pandas as pd
import numpy as np
def get_tag(site_url):
"""
指定したURLでのh1、h2、h3タグの内容を、1次元配列で返す。
Parameters
-------------------
param1: サイトのURL
Returns
-------------------
インプットしたURLの1次元リスト:[h1の文字列, h2の文字列, h3の文字列]
タグが複数ある場合は、'/n'(Macの改行コード)で結合する。
"""
#返り値の配列を初期化
result_tag = []
try:
site_res_google = requests.get(site_url)
#Responseオブジェクトが持つステータスコードが200番台(成功)以外だったら、エラーメッセージを吐き出してスクリプトを停止します。
site_res_google.raise_for_status()
#サイトの文字コードを'utf-8'に指定する
site_res_google.encoding = 'utf-8'
#サイトのHTMLをBeautifulSoupの形式にする
site_bs4_google = bs4.BeautifulSoup(site_res_google.text, 'lxml')
#forループを回すために、h1~h3タグのリストを作る
get_tag_list = ['h1', 'h2', 'h3']
for tag in get_tag_list:
if site_bs4_google.find_all(tag):
tag_list = [_tag.text for _tag in site_bs4_google.find_all(tag)]
result_tag.append('\n'.join(tag_list))
else:
#タグがない場合は、Noneとする
result_tag.append('None')
except:
#処理がエラーになるサイトは、戻り値のリストの要素をすべてNoneとする
result_tag = ['None', 'None', 'None']
return result_tag
search_keyword = 'データサイエンティスト いらない'
print('【検索した単語】{}'.format(search_keyword))
#検索順位取得処理
#Google検索の実施
search_url = 'https://www.google.co.jp/search?hl=ja&num=15&q=' + search_keyword
res_google = requests.get(search_url)
#Responseオブジェクトが持つステータスコードが200番台(成功)以外だったら、エラーメッセージを吐き出してスクリプトを停止します。
res_google.raise_for_status()
print("Google検索結果を取得")
#res_google.textは、検索結果のページのHTML
bs4_google = bs4.BeautifulSoup(res_google.text, 'lxml')
google_search_page = bs4_google.select('div.kCrYT>a')
#rank:検索順位
rank = 1
#Google検索結果ページ上のサイトにおいて、順位、タイトル、URL、タグ(h1,h2,h3)毎にリストを作る。
site_rank_list = []
site_title_list = []
site_url_list = []
site_tag_list = []
#Google検索結果ページ上のサイトに対して、サイト単位で上位からループを回す。
for site in google_search_page:
try:
#サイトのタイトルを取得し、site_rank_listに要素を追加する。
site_title_list.append(site.select('h3.zBAuLc')[0].text)
#サイトのURLを取得する。
url_tmp = site.get('href').split('&sa=U&')[0].replace('/url?q=', '')
#サイトのURLから、get_tag関数を用いて、tagを取得し、site_tag_listに要素を追加する。
site_tag_list.append(get_tag(url_tmp))
#サイトのURLを、site_url_listに要素を追加する。
site_url_list.append(url_tmp)
#サイトの順位を、site_rank_listに要素を追加する。
site_rank_list.append(rank)
#ランキングをインクリメントする。
rank +=1
except IndexError:
continue
print("スクレイピング終了")
#site_tag_list(2次元配列)は、スライスしやすいようにするため、numpy-arrayに変換する。
site_tag_list = np.array(site_tag_list)
#CSVに保存するために、DataFrame形式にする
df = pd.DataFrame({'順位':site_rank_list, 'タイトル':site_title_list, 'URL':site_url_list, 'h1':site_tag_list[:,0],
'h2':site_tag_list[:,1], 'h3':site_tag_list[:,2]})
#CSVファイルにエクスポートする。ファイル名は、検索ワードとする。
df.to_csv(search_keyword+'.csv', index=False)
print("CSVファイルへの書き込み終了")
PythonでのWebスクレイピングの実行結果
上のソースを実行すると、下の図のようなCSVファイルが出来上がります。
以上になります。
もしこうした方がいいよ〜とか、ここが分からない等ありましたら、Twitterまで連絡をお待ちしています。
読んでいただき、ありがとうございました。