前の記事でConoHaというVPSにDockerとdocker-composeの環境を構築しました。なぜ構築したかというと…Seleniumを動かしたかったからです。正直なところ別にDocker上で動かす必要は無いのですが、一度、Docker環境で動かせるようになっておけば、他環境にも入れやすくなるのでやってみました。
というわけで今回は、ConoHa上のDockerでサクッとSeleniumを動かすことによって、ちょっとした自動操作をやってみたいと思います。GUIがない環境でも動くようにヘッドレス、ChromeとFirefoxで動かすのを目標にやっていきます。
Selenium?
SeleniumはWebアプリケーションのテスト用に開発されているフレームワークです。テスト用ではありますが、自動でWebページを操作できるというのは色々夢が広がります。動作テスト、情報の収集、タスクの自動化など…。Seleniumを動かせる言語は色々とありますが、今回はPythonでやっていきたいと思います。
Dockerfile! docker-compose.yml!
さて、今回はサクッとが目標なので、本題に入ります。まずはdocker-compose.ymlです。これだけあればほぼほぼ構築が完了するんですからDocker…コンテナの技術ってネ申ですね。
version: '3'
services:
selenium-hub:
image: selenium/hub
container_name: 'selenium-hub'
ports:
- 4444:4444
environment:
- GRID_TIMEOUT=300
restart: always
chrome:
image: selenium/node-chrome-debug
container_name: 'chrome'
links:
- selenium-hub:hub
ports:
- 5900:5900
environment:
- NODE_MAX_INSTANCES=5
- NODE_MAX_SESSION=5
- no_proxy=localhost
- HUB_ENV_no_proxy=localhost
- HUB_PORT_4444_TCP_ADDR=selenium-hub
- HUB_PORT_4444_TCP_PORT=4444
- SCREEN_WIDTH=1440
- SCREEN_HEIGHT=900
volumes:
- /dev/shm:/dev/shm
restart: always
firefox:
image: selenium/node-firefox-debug
container_name: 'firefox'
links:
- selenium-hub:hub
ports:
- 5901:5901
environment:
- NODE_MAX_INSTANCES=5
- NODE_MAX_SESSION=5
- no_proxy=localhost
- HUB_ENV_no_proxy=localhost
- HUB_PORT_4444_TCP_ADDR=selenium-hub
- HUB_PORT_4444_TCP_PORT=4444
- SCREEN_WIDTH=1440
- SCREEN_HEIGHT=900
volumes:
- /dev/shm:/dev/shm
restart: always
python:
build: './python-selenium'
container_name: 'python'
links:
- selenium-hub:hub
working_dir: '/root/script/'
volumes:
- ./script/:/root/script/
environment:
- 'TZ=Asia/Tokyo'
tty: true
restart: always
これをdocker-compose.yml
に記述します。これだけでSeleniumとChrome,Firefoxの作業環境が構築されます。端末自体にChromeやFirefoxをインストールする必要すらありません。ちなみに各コンテナは上から「SeleniumGrid」「Chrome」「Firefox」「Python実行環境」の機能を提供してくれます。そのため、Python以外の言語で動かしたければ、4つ目のコンテナを変えてもらうだけで動いてくれると思います。
あとはいい感じにPython環境を構築してもらうようにDockerfile
を書いていきます。ここでの「いい感じ」とは使用するライブラリ類をインストールしてくれるというだけです。
FROM python:3
# seleniumをインストール
RUN apt-get update
COPY ./requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
selenium
はい。これだけです。ここでやっていることはPython側から呼び出すためにSeleniumのライブラリを入れているだけになります。インストールのためにrequirements.txtを用意します。もし他にもインストールしておきたいライブラリなどがあれば、このテキストファイルに1行に1つずつ書いていくだけでビルド時にインストールしてくれます。
ファイル構成
以上の準備が終わると以下のようになります。(sample.pyはこれから書きます!)
.
├── docker-compose.yml
├── python-selenium
│ ├── Dockerfile
│ └── requirements.txt
└── script
└── sample.py
Python!
さて環境は整ったので、次はコードを書いていきます。今回はよくあるテストということで、おなじみGoogleさんで自動検索をしてみようと思います。…それだけではつまんないので、スクリーンショットも撮ってみます。
#!/usr/local/bin/python3
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
def execSearch(browser: webdriver, img_name: str):
"""
Googleで検索する
:param browser: webdriver
"""
# Googleにアクセス
browser.get('https://www.google.co.jp/')
WebDriverWait(browser, 15).until(EC.presence_of_all_elements_located)
# キーワードの入力
search_box = browser.find_element_by_name("q")
search_box.send_keys('hello selenium')
# 検索実行
search_box.submit()
WebDriverWait(browser, 15).until(EC.presence_of_all_elements_located)
# スクリーンショット
browser.save_screenshot(img_name + '.png')
if __name__ == '__main__':
try:
# UA を設定
capabilities = webdriver.common.desired_capabilities.DesiredCapabilities.CHROME.copy()
capabilities['javascriptEnabled'] = True
options = webdriver.ChromeOptions()
options.add_argument('--user-agent="Mozilla/5.0 (Linux; Android 4.0.3; SC-02C Build/IML74K) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.58 Mobile Safari/537.31"')
# HEADLESSブラウザに接続
browser = webdriver.Remote(
command_executor='http://selenium-hub:4444/wd/hub',
desired_capabilities=DesiredCapabilities.CHROME,
options=options
)
browser2 = webdriver.Remote(
command_executor='http://selenium-hub:4444/wd/hub',
desired_capabilities=DesiredCapabilities.FIREFOX
)
# FBで実行
execSearch(browser, img_name='chrome')
execSearch(browser2, img_name='firefox')
browser.close()
browser2.close()
finally:
# 終了
pass
はい。やっていることはコメントのとおりですが。これだけで、ChromeとFirefoxでGoogleにアクセス&「Hello Selenium」と検索、結果のところでスクリーンショットという処理を行います。
実行!
はい。では最後に実行します。
$ cd [docker-compose.ymlがあるディレクトリ]
$ docker-compose up -d --build
$ docker exec -it python python /root/script/sample.py
はい。これで実行もできて、script
ディレクトリの下には検索結果のスクリーンショットも出力されます。またVNCでブラウザコンテナのポートを指定すると動作している画面を表示することもできます。今回ならlocalhost:5900
でOK。
終わりに!
はい。これでいろんな環境でSeleniumが動かせますね。今回作業した内容は下記のリポジトリでまとめておきますので参考までにどうぞ!
次はここで構築したSeleniumを使って何かやりたいと思います。それでは!