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

以下の記事の続きです。

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

今回は、経済産業省のプレスリリースから、過去のアーカイブをまとめて取得して、csvファイルに保存します。

まずは、前回のコードをアーカイブのページのURLを対象にして実行し、問題なく動作することを確認します。

CSVへの保存

まずは1ページのみクロールし、結果をcsvに保存してみます。

プレスリリースの日付、タイトル、リンクをcsvとして保存します。

モジュールのインポート

csvファイルを扱うので、csvというモジュールもインポートします。

csv — CSV ファイルの読み書き

>>> import csv
>>> from selenium import webdriver

csvファイルの作成

列の名前が、それぞれ、日付, タイトル, リンクというcsvファイルを作成します。日本語を扱うため、文字コードをutf8で指定します。

>>> with open('results_meti_press.csv', 'w', encoding='utf8') as f:
...     f.write('日付, タイトル, リンク\n')
...
14

フォルダに列名のみのcsvファイルが作成されました。

情報の取得

次に、前回と同じようにページをクロールして必要な情報を取得します。

>>> driver = webdriver.Chrome()

DevTools listening on ws://127.0.0.1:57775/devtools/browser/717d17cc-e6dc-48c5-9a32-eaa73290c1f9
>>> driver.get('https://www.meti.go.jp/press/archive_201905.html')
>>>
>>> dates = driver.find_elements_by_xpath('//div[@class="left txt_box"]/p')
>>> texts = driver.find_elements_by_xpath('//div[@class="left txt_box"]/a')

取得した情報のcsvへの保存

取得した情報を、ループを回してcsvファイルに保存します。前回はprintで出力していたものをcsvファイルに置き換えます。

>>> num_page_dates = len(dates)
>>> with open('results_meti_press.csv', 'a', encoding='utf8') as f:
...     for i in range(num_page_dates):
...         f.write(dates[i].text + ',' + texts[i].text + ',' + texts[i].get_attribute('href')+ '\n')
...
108
# 省略
117
>>>

csvファイルが取得できました。

ブラウザをクローズしておきます。

>>> driver.close()

アーカイブをまとめてクロール

次にアーカイブをまとめてクロールする方法を考えます。

アーカイブのurlを眺めると、archive_201903.htmlいうように、archive_ + 年 + 月 + .htmlという構成になっていることが分かるので、これらをループで生成します。

モジュールのインポート

年月日を扱うためのモジュールをインポートします。

datetime — 基本的な日付型および時間型

>>> import datetime

年月日の計算を楽にするモジュールをインポートします。

dateutil – powerful extensions to datetime

>>> from dateutil.relativedelta import relativedelta

年と月の算出

今日の日付を出力します。

>>> today = datetime.date.today()
>>> today
datetime.date(2019, 5, 24)

今日の一か月前の日付を出力します。

>>> today + relativedelta(months=-1)
datetime.date(2019, 4, 24)

今日の一か月前の年と月を出力します。

>>> year = (today + relativedelta(months=-1)).strftime('%Y')
>>> year
'2019'
>>> month = (today + relativedelta(months=-1)).strftime('%m')
>>> month
'04'

URLの生成

先月のアーカイブのURLを出力します。

>>> url = 'https://www.meti.go.jp/press/archive_{}{}.html'.format(str(year), str(month))
>>> url
'https://www.meti.go.jp/press/archive_201904.html'

先月のアーカイブのurlを取得できたので、今度はループで過去10か月分のアーカイブのurlを取得して、リストにします。

>>> url_list = []
>>> for i in range(10):
...     month = (today + relativedelta(months=-i)).strftime('%m')
...     year = (today + relativedelta(months=-i)).strftime('%Y')
...     url = 'https://www.meti.go.jp/press/archive_{}{}.html'.format(str(year), str(month))
...     url_list.append(url)
...
>>> url_list
['https://www.meti.go.jp/press/archive_201905.html', 'https://www.meti.go.jp/press/archive_201904.html', 'https://www.meti.go.jp/press/archive_201903.html', 'https://www.meti.go.jp/press/archive_201902.html', 'https://www.meti.go.jp/press/archive_201901.html', 'https://www.meti.go.jp/press/archive_201812.html', 'https://www.meti.go.jp/press/archive_201811.html', 'https://www.meti.go.jp/press/archive_201810.html', 'https://www.meti.go.jp/press/archive_201809.html', 'https://www.meti.go.jp/press/archive_201808.html']

アーカイブのurlのリストが生成できたので、このリストをループで回せば、アーカイブのページを巡回できます。

アーカイブ巡回コードの作成

csvとして保存するコードと、urlを生成するコードを、一つのコードにまとめます。

import csv
import datetime

from dateutil.relativedelta import relativedelta
from selenium import webdriver 

# アーカイブを取得する月数
MONTHS = 10
today = datetime.date.today()

# アーカイブのurlを生成、リストに保存
url_list = []
for i in range(MONTHS):
    month = (today + relativedelta(months=-i)).strftime('%m')
    year = (today + relativedelta(months=-i)).strftime('%Y')
    url = 'https://www.meti.go.jp/press/archive_{}{}.html'.format(str(year), str(month))
    url_list.append(url)

# csvファイルの生成
with open('results_meti_press.csv', 'w', encoding='utf8') as f:
    f.write('日付, タイトル, リンク\n')

driver = webdriver.Chrome()

# アーカイブのクロールとcsvへの情報の保存
for url in url_list:
    driver.get(url)

    dates = driver.find_elements_by_xpath('//div[@class="left txt_box"]/p')
    texts = driver.find_elements_by_xpath('//div[@class="left txt_box"]/a')

    num_page_dates = len(dates)
    with open('results_meti_press.csv', 'a', encoding='utf8') as f:
        for i in range(num_page_dates):
            f.write(dates[i].text + ',' + texts[i].text + ',' + texts[i].get_attribute('href')+ '\n')
 
driver.close()

実行すると無事にcsvファイルが取得できました。