LoginSignup
67
80

DockerでPython-Seleniumスクレイピング環境を立てた

Last updated at Posted at 2021-05-01

はじめに

メイン機以外で定期実行されるクローラを作りたいと思ったわけですが、その場合ローカル環境に全く依存しない形が取れれば最高だということで、Docker環境の構築に乗り出しました。

全体図

2021-05-01_11h13_41.jpg

Python実行環境とSeleniumHQ/docker-seleniumはDocker Composeを利用して別のコンテナとして立てます。
そしてSeleniumHQ/docker-seleniumを通じてVNC接続することで、簡単にクローラの挙動をチェックできます。

ちなみに、SeleniumHQ/docker-seleniumがあれば、ChromeやChromeDriverのセットアップは不要です。

環境構築

Docker

最近はWindows10 Homeでも簡単にインストールできるようになったようです。
Dockerのインストーラの指示に従っていれば使える状態になります。

VSCode(任意)

Remote-Containersプラグインによって、ローカル開発のような感覚でデバッグも楽々です。
docker-compose.ymlDockerfileの他に、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.ymlapp\Dockerfileによって生成されるイメージとSeleniumHQ/docker-seleniumイメージからコンテナを立てます。

build.sh

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

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

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

requirements.txt
autopep8
selenium

本来はpip freeze > /app/requirements.txtした方がいいのですが、少し自由度を持たせています。

test.py

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

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

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

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:5901secret

接続ができたら何かロゴが表示されている状態だろうと思います。

テストスクリプト実行

python /app/src/test.py

すると、VNCビューワ内でブラウザが表示されると思います。
コンソールに何かが表示されれば動作確認完了です。

VSCodeでコーディング

あとは、Remote-Containersの機能を利用し、VSCodeでDocker環境に入りコーディングするだけです。
必要なパッケージなどあれば、requirements.txtに追記してリビルドしておきます。

さいごに

この程度のことは結構な人数が発信していそうでしたが、意外と正解が見つからずに苦戦しました。
自分自身は、Pythonでスクレイピングする用事があれば上記のリポジトリをクローンするところから始めています。
便利なのでぜひご活用ください。

67
80
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
67
80