Anaconda イメージに Chrome をインストールしてみたり していたが、やはりビルドに時間がかかってしまってしんどいので Chrome 部分だけ別イメージとして切り出せないかと考えていたところ、WebDriver の操作を REST API 経由で行える Selenium Grid なる仕組みがあることを知ったので試してみた。
Selenium Grid を起動する
Selenium Grid を利用できる Docker イメージが公式から公開されているのでこれを使う。
SeleniumHQ/docker-selenium: Docker images for Selenium Grid Server (Standalone, Hub, and Nodes).
複数のブラウザを使う場合は Hub と各ブラウザの Node をそれぞれ立ち上げる必要があるが、今回は Chrome で試したいだけなので Standalone のイメージを使った。
version: "3"
services:
chrome:
image: selenium/standalone-chrome
ports:
- 4444:4444
volumes:
- /dev/shm:/dev/shm
ポート 4444 で REST API が公開される。
WebDriver を操作する API は /wd/hub
らしい。
$ docker-compose up
Python から Selenium Grid を使う
Python から Selenium Grid を使う場合は selenium.webdriver.Remote
を利用する。
$ pip3 install selenium
import sys
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
def search(driver, query):
driver.get('https://google.com/')
q = driver.find_element_by_name('q')
q.send_keys(query)
q.submit()
r = driver.find_element_by_class_name('g').find_element_by_class_name('r')
title = r.find_element_by_tag_name('h3').text
url = r.find_element_by_tag_name('a').get_attribute('href')
return title, url
if __name__ == '__main__':
query = ' '.join(sys.argv[1:])
options = {
'command_executor': 'http://localhost:4444/wd/hub',
'desired_capabilities': DesiredCapabilities.CHROME,
}
with webdriver.Remote(**options) as driver:
title, url = search(driver, query)
print(f'{title}\n{url}')
Google 検索して結果トップのタイトルと URL を表示するスクリプトを書いてみた。
$ python3 main.py qiita
Qiita
https://qiita.com/