seleniumを使ったスクレイピングの基本操作

かばくん

最近よく聞くスクレイピングとはなんですか?
ぼくでもできますか??

へびせんせい

スクレイピングとは主にWebから自動的に情報を取得することを指します。
seleniumというライブラリを使えば、簡単に実装可能です。

pythonによるseleniumを使ったスクレイピングの基本操作をまとめます

準備

必要なもの

pip install selenium
pip install webdriver_manager

実装するもの

スクレイピング用のサンプルサイトを用いて、スクレイピングを行ってみます。

サンプルサイトはこちら

次のことを実装してみます。

  1. テキスト情報の取得
  2. 表(Table)データの取得
  3. 画像のダウンロード
  4. テキストの入力とボタンのクリック

seleniumを使ったスクレイピング

seleniumを使ったスクレイピングは、「ウェブブラウザの自動操縦」という感覚に近いです。
動作しているところを見てみるとわかりやすいのですが、実際の人間の操作を機械的に行うようなものです。
最近よく使われるRPAという技術に非常によく似ています。
これは、良い面もあれば悪い面もあります。

seleniumの良いところ
  • 動作を実際に見ながら確認できる
  • inputボックスに値を入力する、ボタンを押す等の実際の操作を行える
  • スクレイピング対策に強い
seleniumの悪いところ
  • 動作が遅い
  • 処理や画面更新の待ち時間を考慮しなければならない
  • Webサイトのhtml構造の更新に弱い

ライブラリのインポート

import selenium
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys

Optionsはheadlessモードを使う際に必要で、Keysは画面スクロールをするときに使います。
ともに不要であれば、インポートしなくてもよいです。

webdriver_managerについて

from webdriver_manager.chrome import ChromeDriverManager

seleniumでは実際にウェブブラウザを操作することになります。
その際に、プログラム上でブラウザを動かすためのウェブドライバーというものが必要になります。
このウェブドライバーは実際に使用するブラウザのバージョンに合ったウェブドライバーをインストールする必要があります。
しかし、使用しているブラウザのバージョンは環境によってまちまちであることが大半であり、その環境に合わせてウェブドライバーをインストールするのは煩雑です。
このwebdriver_managerを使えば、自動的に環境に適したドライバーをインストールしてくれます。

headlessモード

options = Options()
options.add_argument('--headless')

optionにheadlessモードを指定すると、chromeをヘッドレスモードで実行できます。
headlessモードとは、ブラウザを画面上に表示することなく自動操作を実行するものです。
もし、はじめてスクレイピングを実行する場合は、headlessモードだと何が起きているか分からないので、このoptionの記述は不要です。

サイトへのアクセス

url = "https://www.next1step.com/category/python/scraping_sample_page/"
driver = webdriver.Chrome(ChromeDriverManager().install(), options=options)
driver.implicitly_wait(10)          
driver.get(url)

変数urlにスクレイピング用のサンプルページを指定しています。実行することで、実際にchromeが起動して指定したページが開かれます。

seleniumでchromeを起動して、指定のサイトにアクセスしたところ

実際にプログラムを実行すると、勝手にブラウザが起動して、サンプルページにアクセスされます。
chromeに「自動テストソフトウェアによって制御されています。」と表示されます。なんとなく自動操作してる感がでてます。

要素の取得

スクレイピングで必要な情報を取得するには、必要なHTML要素にアクセスしなければなりません。
ここがスクレイピングの難しいところでもあり、技の見せ所でもあります。
タグ・ID・class・xpathなどのHTMLの知識も少なからず必要となります。

今回は、「へびせんせいについて」というテキスト、得意なプログラミングの一覧、へびせんせいの画像のダウンロード、日本に生息するへびの毒の有無の表データを取得してみます。
そして、inputボックスに名前とメールアドレスを入力して、ボタンを押してみます。

見出しのテキスト情報を取得

## タグ指定:h2要素を取得する
elems = driver.find_elements_by_tag_name("h2")
elem = elems[0]

print(elem.text)

ページ内のすべてのh2要素をリスト形式で取得します。
リストの中から必要な要素だけを選択して、テキストを出力します。

箇条書きになっているテキストの取得

## liの取得
elems = driver.find_element_by_tag_name("article").find_elements_by_tag_name("li")

for elem in elems:
    print(elem.text)

「得意なプログラミング」の下にある箇条書き部分を取得しています。
h2要素と同じようにすべてのli要素をリスト形式で抽出でもよいのですが、ヘッダー部分の不要なliタグも取得してしまいます。
そのため、articleタグの中のすべてのliタグを指定することで、うまく箇条書き部分を取得しています。

画像のダウンロード

## 画像をダウンロードする
# seliniumでは、画像の保存をスクリーンショットとして保存できる

img_elem = driver.find_element_by_xpath("//img[contains(@alt,'サンプル画像')]")

with open("out.png", "wb") as f:
    f.write(img_elem.screenshot_as_png)

こちらは、xpathを使ってimgタグのalt属性に「サンプル画像」というテキストが含まれているものを取得しています。
要素が正しく選択できたら、openメソッドを使ってファイルを保存します。

表(Table)のデータの取得

## テーブルの情報を取得する
elem = driver.find_element_by_tag_name('table')
tds = elem.find_elements_by_tag_name('td')

for i in range(int(len(tds)/2)):
    print(tds[i * 2].text + '  ' + tds[i * 2 + 1].text)

表データはtableタグの中のtdタグにデータが格納されています。
上手く表と同じ形式で出力するように、printさせています。

テキスト入力、ボタンクリック

## テキストボックスに文字を入力し、ボタンを押す
name_elem = driver.find_element_by_name('name')
mail_elem = driver.find_element_by_name('mail')
button_elem = driver.find_element_by_xpath("//input[@value='確認する']")

driver.find_element_by_tag_name('body').send_keys(Keys.END)
name_elem.send_keys('かばくん')
mail_elem.send_keys('kabakun@xxxxxx.xx')
button_elem.click()

テキストの入力はsend_keysメソッドを使うことで、入力可能です。もちろん変数も使えるので、自由にテキスト入力可能です。
ボタンを押すのも簡単で、button要素を指定した上で、click()メソッドを使うことでクリックされ、次のページに遷移されます。

button要素をclick()するときは、そのボタンが画面上に表示されている必要があります。
今回は、send_keysメソッドでENDキーを送信して、画面を一番下までスクロールしています。

ブラウザを閉じる

# ブラウザの終了
driver.quit()

かばくん

自動的にブラウザが動いていくので見てて楽しい。
へびせんせいにもメールが送れちゃったよ!


1つにまとめたファイルのGitリポジトリ

Download