Seleniumとは

自動でブラウザを操作させるツールです。
Webサイトのテストスクレイピングを自動化するのに使います。

Seleniumの歴史にいろいろあって、古い記事を見ると難しそうな印象を受けますが、そんなことはないです。

Selenium IDE

もともとはFirefoxのアドオン(拡張機能)でしたが、バージョンが上がって、使用できなくなりました。
新しくSelenium IDEが作られ、ChromeとFirefoxに対応しましたが、いくつかの機能が足りないようです。

インストールは、ブラウザにアドオンを入れるだけなので、とても楽です。
操作方法も手順を保存して実行するだけなので、簡単に扱えます。

Chrome版 Selenium IDE

Firefox版 Selenium IDE

Selenium WebDriver

Selenium WebDriverは、プログラムで動かします。
Selenium IDEより面倒かもしれませんが、複雑な操作をする場合、こちらの方が良いです。

PythonでSelenium

Selenium WebDriverは、複数のプログラム言語に対応しています。
スクレイピングのことも考えて、私はPythonを選びました。

Pythonをインストール

私は過去にいろいろやったので分かりませんが、MacではPythonが最初から入っているようです。
3を入れたかったので、HomebrewでPython3をインストールしました。
私の環境では、python3となっていますが、このままいきます。

$ python -V
Python 3.7.0 (default, Sep 21 2018, 17:00:16)
[Clang 10.0.0 (clang-1000.11.45.2)]

pyenvで、バージョンを切り替える手もあるみたいです。

Seleniumをインストール

Pythonのpip(Pythonのパッケージ管理システム)でSelenium WebDriverをインストールします。
私の環境だとpipは、pip3となっています。

$ pip install selenium

Google Chrome Driverをインストール

操作するブラウザに対応したdriverをインストールする必要があります。
とりあえずGoogle Chrome Driverにしました。

brew caskでインストールできるようなので、それで入れます。

$ brew cask install chromedriver

Seleniumを動かす

動くかどうか、test.pyを作ります。

test.py

from selenium import webdriver

driver = webdriver.Chrome()
driver.get('https://www.yahoo.co.jp/')

ターミナルなどから実行してみます。

$ python test.py

ブラウザが起動して、サイトが表示されれば、問題ないです。

Seleniumをいろいろ動かす

test.pyを書き換えて、いろいろ動かしてみます。

キーワードを検索して表示

Yahoo! JAPANでツクメモを検索してみます。

from selenium import webdriver

driver = webdriver.Chrome()
driver.get('https://www.yahoo.co.jp/')

driver.find_element_by_id('srchtxt').send_keys('ツクメモ')
driver.find_element_by_id('srchbtn').click()

Headless

ブラウザを起動せずに動かしたい場合、Headlessモードを使います。
そのままだと、何か起きた感じがしないので、内容をターミナルに表示します。

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

options = Options()
options.headless = True

driver = webdriver.Chrome(options=options)
driver.get('https://www.yahoo.co.jp/')

driver.find_element_by_id('srchtxt').send_keys('ツクメモ')
driver.find_element_by_id('srchbtn').click()

WS2m = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, 'WS2m')))
for e in WS2m.find_elements_by_tag_name('h3'):
	print(e.text)

driver.quit()

要素にアクセス

find_element_byで、htmlの要素にアクセスします。

find_element_by_id id属性でアクセスします。
find_element_by_name name属性でアクセスします。
find_element_by_xpath XPath(XMLやHTMLから、文章を抽出する記述方法)でアクセスします。
find_element_by_link_text リンクのテキストで要素にアクセスします。
find_element_by_partial_link_text リンクのテキストの一部分から要素にアクセスできます。
find_element_by_tag_name HTMLのタグの名前でアクセスします。
find_element_by_class_name class属性でアクセスします。
find_element_by_css_selector スタイルシートの書き方でアクセスします。

いくつもある要素は、elementsとすると、複数にアクセス可能になります。

  • find_elements_by_name
  • find_elements_by_xpath
  • find_elements_by_link_text
  • find_elements_by_partial_link_text
  • find_elements_by_tag_name
  • find_elements_by_class_name
  • find_elements_by_css_selector

アクションする

今回は入力とクリックしか使っていません。

文字を入力

driver.find_element_by_id('srchtxt').send_keys('ツクメモ')

要素をクリック

driver.find_element_by_id('srchbtn').click()

待機する

アクションのあとに要素を待ってから処理を実行したいときに使います。
複雑な動作では、待機を使うとうまくいく場合が多いです。

WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, 'WS2m')))

待機する条件

待機する条件は、いくつか選択できます。
よく使ったものだけメモします。

presence_of_element_located 要素がDOMに現れるまで待機
visibility_of_element_located 要素が可視されるまで待機
invisibility_of_element_located 要素が不可視されるまで待機
element_to_be_clickable 要素がクリックできる状態になるまで待機

テキストを表示

要素のinnerTextを表示します。

driver.find_element_by_css_selector('#WS2m h3').text

終了

Headlessの場合、意味があるのか、ちょっと分かりません。
ブラウザを終了します。

driver.quit()