[Python] Seleniumを使ってみる (1)

Selenium

Seleniumは、webアプリケーションのテストのためのフレームワークですが、スクレイピングでも良く使われます。Seleniumを使うことで、webブラウザを操作することができます。

公式サイト

今回はPythonでSeleniumを使うことで、経済産業省の最新のプレスリリースを抜き出してみます。

Seleniumのインストール

pip でインストールします。

$ pip install selenium

Webドライバのインストール

seleniumのwebドライバとは、seleniumからそれぞれのブラウザの操作を可能にするものです。自分が操作したいブラウザに応じて、そのブラウザのwebドライバが必要になります。今回はChromeを使います。

Chromeのwebドライバは下記からダウンロードできます。

ChromeDriver – WebDriver for Chrome

ダウンロードしたら、適当なフォルダに保存して、PATH環境変数でそのフォルダを指します。

インポートとブラウザの起動

インポートしてブラウザを起動してみます。

>>> from selenium import webdriver
>>> driver = webdriver.Chrome()

DevTools listening on ws://127.0.0.1:65279/devtools/browser/9649b2ed-f847-4e84-b756-48468e1cfd9b

空のブラウザが起動します。

次に開いたブラウザで、経済産業省の目的のページに遷移します。

>>> driver.get('https://www.meti.go.jp/press/')

経済産業省のプレスリリースのページが開きます。

必要な情報の取得と表示

目的とする情報を取得します。

今回は、プレスリリースの日付とタイトルを取得します。

まず、chromeの検証ツールで目的のソースを確認します。

Seleniumにも多くの要素の指定方法がありますが、今回は汎用的に使えるXpathを使います。

Xpath

XML Path Language (XPath(エックスパス)) は、マークアップ言語XML に準拠した文書の特定の部分を指定する言語構文である。

出典: フリー百科事典『ウィキペディア(Wikipedia)』

スクレイピングのためのXpathの記法については、以下がとても分かりやすいです。

クローラ作成に必須!XPATHの記法まとめ

以下はシンプルにまとまっています。

XPath Syntax

日付とタイトルの取得と表示

日付を取得します。

>>> dates = driver.find_elements_by_xpath('//div[@class="left txt_box"]/p')
>>> dates
[‹selenium.webdriver.remote.webelement.WebElement (session="689b6c2e10e4e2f9e1373136d9d439ea", element="0.8309477759767074-1")›, 
# 長いので省略
‹selenium.webdriver.remote.webelement.WebElement (session="689b6c2e10e4e2f9e1373136d9d439ea", element="0.8309477759767074-20")›]

取得したwebelementオブジェクトの中身を見てみます。

>>> dates[0].get_attribute('innerHTML')
'2019年5月23日'
>>> dates[0].text
'2019年5月23日'

タイトルを取得します。

>>> texts = driver.find_elements_by_xpath('//div[@class="left txt_box"]/a')
>>> texts
[‹selenium.webdriver.remote.webelement.WebElement (session="689b6c2e10e4e2f9e1373136d9d439ea", element="0.8309477759767074-21")›,
# 長いので省略
‹selenium.webdriver.remote.webelement.WebElement (session="689b6c2e10e4e2f9e1373136d9d439ea", element="0.8309477759767074-40")›]

取得したwebelementオブジェクトの中身を見てみます。

>>> texts[0].get_attribute('innerHTML')
'「国際化促進インターンシップ事業」参加企業を募集中です'
>>> texts[0].get_attribute('href')
'https://www.meti.go.jp/press/2019/05/20190523001/20190523001.html'
>>> texts[0].text
'「国際化促進インターンシップ事業」参加企業を募集中です'

無事に取得できているようなので、ループで全て表示してみます。

>>> num_page_dates = len(dates)
>>> for i in range(num_page_dates):
...     print(dates[i].text + ' : ' + texts[i].text)
...
2019年5月23日 : 「国際化促進インターンシップ事業」参加企業を募集中です
2019年5月22日 : 「さらなる対話型株主総会プロセスに向けた中長期課題に関する勉強会とりまとめ(案)」についての意見・情報提供を募集します
2019年5月22日 : 「スマートモビリティチャレンジ シンポジウム」を開催します
2019年5月21日 : レジメーカー・システムベンダー各社との「消費税軽減税率対応への強化・加速化に向けた特別会合」を開催しました
2019年5月21日 : 「夏季の省エネルギーの取組について」を決定しました
2019年5月21日 : プラットフォーマー型ビジネスの台頭に対応したルール整備に関するオプションを公表しました
2019年5月21日 : TCFDコンソーシアムが設立されます
2019年5月21日 : METIナッジユニットを設置しました
2019年5月21日 : 令和元年春の勲章受章者が決定されました(経済産業省推薦分)
2019年5月20日 : 日本工業規格(JIS)を制定・改正しました(2019年5月分)
2019年5月20日 : 第4回「第四次産業革命スキル習得講座」を認定しました
2019年5月20日 : ロボットサービスの安全規格(JIS)を制定しました
2019年5月20日 : 石川経済産業大臣政務官がベルギーに出張しました
2019年5月20日 : 石川経済産業大臣政務官がAPEC貿易担当大臣会合へ出席しました
2019年5月20日 : 令和元年春の褒章受章者が決定されました(経済産業省推薦分)
2019年5月17日 : 磯﨑経済産業副大臣がG7デジタル閣僚会合に出席しました
2019年5月17日 : WTO上級委員会報告書の結果を踏まえた対応方向について
2019年5月17日 : 地域未来投資促進法に基づく連携支援計画を承認しました
2019年5月17日 : 地域未来投資促進法に基づく地方自治体の基本計画に同意しました
2019年5月17日 : 高齢化社会における製品安全に関する課題調査報告を取りまとめました

表示できました。

ブラウザを終了する

最後にブラウザを終了します。

>>> driver.close()
[14156:17104:0523/131015.814:ERROR:browser_process_sub_thread.cc(217)] Waited 12 ms for network service

コード

コードにまとめます。

from selenium import webdriver 

driver = webdriver.Chrome()
driver.get('https://www.meti.go.jp/press/')

# //*[@id="main"]/div[3]/ul[2]/li[1]/div[2]/p
dates = driver.find_elements_by_xpath('//div[@class="left txt_box"]/p')
#//*[@id="main"]/div[3]/ul[2]/li[1]/div[2]/a
texts = driver.find_elements_by_xpath('//div[@class="left txt_box"]/a')

num_page_dates = len(dates)
for i in range(num_page_dates):
    print(dates[i].text + ' : ' + texts[i].text)

driver.close()

以下に続きます。

以下の記事の続きです。 今回は、経済産業省のプレスリリースから、過去のアーカイブをまとめて取得して、csvファイルに保存します。 まずは、前回のコードをアーカイブのページのURLを対象にして実行し、問題なく動作することを確認します。 CSVへの保存...