Dockerでseleniumを動かす

ブラウザを使うオペレーター業務や運用の自動化に、seleniumというフレームワークがよく使われています。

PCにインストールされたブラウザをプログラミングで直接操作できるようになり、とても便利です。

今回、このseleniumを使って試したいことがあって、CUIでも手軽に扱える環境をdockerで構築しました。その知見をシェアします。

ディレクトリ構成

下記はディレクトリ構成です。

.
├── app
│   └── test.py
├── docker-compose.yml
└── selenium.dockerfile

selenium.dockerfile

docker hubにseleniumのイメージがありました。しかしnode.jsの使用に限定されているようだったので、Python用にdockerfileを書くことにしました。

FROM python:3.7-alpine

ENV PYTHONIOENCODING utf-8
WORKDIR /app

RUN apk add --update \
        wget \
    # Add chromium and dependences
        udev \
        ttf-freefont \
        chromium \
        chromium-chromedriver \
    # Add Japanese font
    && mkdir noto \
    && wget -P /app/noto https://noto-website.storage.googleapis.com/pkgs/NotoSansCJKjp-hinted.zip \
    && unzip /app/noto/NotoSansCJKjp-hinted.zip -d /app/noto \
    && mkdir -p /usr/share/fonts/noto \
    && cp /app/noto/*.otf /usr/share/fonts/noto \
    && chmod 644 -R /usr/share/fonts/noto/ \
    && fc-cache -fv \
    && rm -rf /app/noto \
    # Add selenium
    && pip install selenium

FROM python:3.7-alpine…イメージのベースは軽量なAlpineを使います。

chromium はGoogleのchromeブラウザをベースにしたオープンソースのプロジェクトで、速度と安定性を売りにしています。今回はこいつを使います。

chromium-chromedriver…これはseleniumでchromiumを動かすためのドライバです。

そのほか、日本語対応のためにGoogleのnotoフォントをインストールしています。

pip install selenium 最後の行で、seleniumをインストールしています。

docker-compose.yml

マルチコンテナの実行は考えていませんが、Volumeのマウントなどが簡単になるのでdocker composeを使うことにしました。下記はymlファイルの中身です。

version: '3'

services:
  selenium:
    container_name: selenium
    build:
      context: .
      dockerfile: selenium.dockerfile
    tty: true
    volumes:
        - ./app:/app

test.py

seleniumのテスト用に書いたpythonのコードです。

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service

chrome_path = '/usr/bin/chromium-browser'
chromedriver_path = '/usr/lib/chromium/chromedriver'
o = Options()
o.binary_location = '/usr/bin/chromium-browser'
o.add_argument('--headless')
o.add_argument('--disable-gpu')
o.add_argument('--no-sandbox')
o.add_argument('--window-size=1200x600')

"""
Sample test
"""
d = webdriver.Chrome(chromedriver_path, options=o)
d.get('https://www.google.com')
print(d.title)
d.quit()

"""
Use the Chrome DriverService.
https://chromedriver.chromium.org/getting-started
"""
s = Service(executable_path=chromedriver_path)
s.start()
d = webdriver.Remote(
    s.service_url,
    desired_capabilities=o.to_capabilities()
)
d.get('https://www.google.com')
print(d.title)
d.quit()

CUIで使うには、seleniumのドライバーに --headless などいくつかオプションを追加する必要があります。

また、webdriver.Chromeを使うより、Service()を使う方が高速に処理できるようです。

参考URL: https://chromedriver.chromium.org/getting-started

コンテナの起動

docker composeを使っているので、 docker-compose up -d で起動します。簡単ですね。我ながらイケてます。

seleniumの実行

試しにtest.pyを動かしてみます。

docker container exec -it selenium python test.py

コンソールに Google の文字が出力されたら成功です。

まとめ

これで色々実験できますね。業務でも使いまわせそうなのでGitHubにあげておきました。

https://github.com/hodanov/docker-selenium