はじめに
メイン機以外で定期実行されるクローラを作りたいと思ったわけですが、その場合ローカル環境に全く依存しない形が取れれば最高だということで、Docker環境の構築に乗り出しました。
全体図
Python実行環境とSeleniumHQ/docker-seleniumはDocker Composeを利用して別のコンテナとして立てます。
そしてSeleniumHQ/docker-seleniumを通じてVNC接続することで、簡単にクローラの挙動をチェックできます。
ちなみに、SeleniumHQ/docker-seleniumがあれば、ChromeやChromeDriverのセットアップは不要です。
環境構築
Docker
最近はWindows10 Homeでも簡単にインストールできるようになったようです。
Dockerのインストーラの指示に従っていれば使える状態になります。
VSCode(任意)
Remote-Containersプラグインによって、ローカル開発のような感覚でデバッグも楽々です。
docker-compose.yml
やDockerfile
の他に、devcontainer.json
なるVSCode用の設定ファイルを用意します。
devcontainer.json
に盛り盛りの設定をすることも可能なようですが、素の状態で実行できなければあまり意味がないので、まずコマンドラインで動作確認をしてからVSCode用の設定を整えるのがいいと思われます。
VNC
Docker環境は完全に閉じた環境なので、ホストマシンのブラウザを見ながらのデバッグができません。
そこで、Docker環境内にあるLinux上のデスクトップ画面を表示するために、VNCという技術を使います。
ディレクトリ構成
.devcontainer\
devcontainer.json
app\
.vscode\
launch.json
settings.json
src\
test.py
Dockerfile
requirements.txt
build.sh
docker-compose.yml
.devcontainer\*
と.vscode\*
はVSCode用の設定ファイルです。
dockcker-compose.yml
でapp\Dockerfile
によって生成されるイメージとSeleniumHQ/docker-selenium
イメージからコンテナを立てます。
build.sh
#!/bin/sh
cd `dirname $0`
docker-compose build --no-cache
docker-compose up -d
docker-compose exec app bash
dockerコマンド入力分の効率化目的です。
3行目(cd ...
)があると、実行場所に制限がなくなって便利です。
docker-compose.yml
version: "3"
services:
selenium:
container_name: python-selenium-on-docker_selenium
image: selenium/standalone-firefox-debug:3.141.59
ports:
- 4444
- 5901:5900
volumes:
- /dev/shm:/dev/shm
app:
container_name: python-selenium-on-docker_app
depends_on:
- selenium
build: ./app
volumes:
- ./app:/app
environment:
SELENIUM_URL: http://selenium:4444/wd/hub
tty: true
-
test.py
内で、環境変数Selenium_URL
を用いてdriver
を定義しています。 -
tty: true
でコンテナの起動状態を維持します。(後でexec
するため) - SeleniumHQ/docker-seleniumでは、Firefoxを利用しています。
- 2021/05/01現在、Docker for Windowsのバグによって、Chromeが動作しないようです。(該当issue)
- どうしてもChromeを利用したければ、
volumes
を/dev/shm:/dev/shm
でなく、shm_size: "2gb"
などとすればいいようです。
Dockerfile
FROM python:3.7-slim-buster
ENV PYTHONIOENCODING utf-8
ENV TZ="Asia/Tokyo"
ENV LANG=C.UTF-8
ENV LANGUAGE=en_US:en
WORKDIR /app
COPY ./requirements.txt /tmp/requirements.txt
RUN pip install -r /tmp/requirements.txt
Python環境のベースイメージは軽量版を利用しています。
wgetやcurlなどで色々入れたい場合は通常版を利用するのが吉でしょう。今回はシンプルな構成なので軽量版で十分でした。
requirements.txt
autopep8
selenium
本来はpip freeze > /app/requirements.txt
した方がいいのですが、少し自由度を持たせています。
test.py
import os
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
driver = webdriver.Remote(
command_executor=os.environ["SELENIUM_URL"],
desired_capabilities=DesiredCapabilities.FIREFOX.copy()
)
driver.implicitly_wait(5)
driver.get("https://www.time-j.net/worldtime/country/jp")
print(driver.find_element_by_xpath("/html/body/div/div[6]/div[1]/div/p[5]").text)
driver.quit()
PCの内蔵時計は、0.2秒遅れています。
Seleniumの動作確認用プログラムです。
こちらから適当な情報を取得しています。
重要な部分は、driver = webdriver.Remote(...
あたりです。
docker-compose.yml
で定義した環境変数SELENIUM_URL
を利用しています。
devcontainer.json
{
"dockerComposeFile": "../docker-compose.yml",
"service": "app",
"workspaceFolder": "/app",
"settings": {
"terminal.integrated.shell.linux": "/bin/bash"
},
"extensions": [
"streetsidesoftware.code-spell-checker",
"ms-python.python",
"ms-python.vscode-pylance",
"njpwerner.autodocstring"
]
}
拡張機能は、好きなものを入れるといいでしょう。
launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
}
]
}
Docker環境にVSCode拡張機能「Remote-Containers」で接続した状態でデバッガを利用できます。
settings.json
{
"python.pythonPath": "/usr/local/bin/python",
"python.languageServer": "Pylance"
}
詳細
GitHubで公開しています。
こちらが最新版です。
https://github.com/ryoheiszk/python-selenium-on-docker
利用手順
上記リポジトリをクローン
自分が再利用しやすいように作ってあるので、便利ではあるだろうと思います。
git clone https://github.com/ryoheiszk/python-selenium-on-docker.git
とりあえずビルド
./build.sh
基本的にLinuxで利用するためにシェルスクリプトとして用意しています。
中身は次のようになっています。
docker-compose build --no-cache
docker-compose up -d
docker-compose exec app bash
VNCテスト
WindowsならVNCViewer等で接続テストをします。
Linuxの場合は、TigerVNCなんかでいいのではないかと思います。
localhost:5901
→secret
接続ができたら何かロゴが表示されている状態だろうと思います。
テストスクリプト実行
python /app/src/test.py
すると、VNCビューワ内でブラウザが表示されると思います。
コンソールに何かが表示されれば動作確認完了です。
VSCodeでコーディング
あとは、Remote-Containersの機能を利用し、VSCodeでDocker環境に入りコーディングするだけです。
必要なパッケージなどあれば、requirements.txt
に追記してリビルドしておきます。
さいごに
この程度のことは結構な人数が発信していそうでしたが、意外と正解が見つからずに苦戦しました。
自分自身は、Pythonでスクレイピングする用事があれば上記のリポジトリをクローンするところから始めています。
便利なのでぜひご活用ください。