【python】DockerでSeleniumを使い動的サイトをスクレイピング

プログラミング

はじめに

Webサイトが静的であれば、requests モジュール等を使ってhtmlの解析ができますが、Javascriptを使った動的サイトであればページが読み込まれてからデータが反映されることもあり、静的サイトのように解析ができません。

そのような動的サイトのスクレイピングは、Selenium というライブラリを使用することで可能になります。ただし、Selenium では走らせるブラウザの WebDriver が必要になります。

今回はSeleniumを使ったWebスクレイピング環境をDockerで構築します。

この記事で使用したソースコードは以下のGitHubで利用できます。

GitHub - Joichiro433/Blog-docker-webscraping
Contribute to Joichiro433/Blog-docker-webscraping development by creating an account on GitHub.

使用するソースコード

今回必要なファイル一式のディレクトリ構造は以下の通りです。

.
├─ dockerfile
├─ main.py
└─ requirements.txt

Dockerfile

使用するdockerfileは次のようになります。

##### building stage #####
FROM python:3.10 as builder

RUN apt-get update && apt-get install -y \
    unzip 

# chrome driver
ADD https://chromedriver.storage.googleapis.com/101.0.4951.41/chromedriver_linux64.zip /opt/chrome/
RUN cd /opt/chrome/ && \
    unzip chromedriver_linux64.zip && \
    rm -f chromedriver_linux64.zip

# python package
RUN pip install --upgrade pip
COPY requirements.txt .
RUN pip install --no-cache-dir -r  requirements.txt


##### production stage #####
FROM python:3.10-slim
COPY --from=builder /opt/ /opt/
COPY --from=builder /usr/local/lib/python3.10/site-packages /usr/local/lib/python3.10/site-packages

RUN apt-get update && apt-get install -y \
    wget \
    curl \
    gnupg

# chrome
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add && \
    echo 'deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main' | tee /etc/apt/sources.list.d/google-chrome.list && \
    apt-get update && \
    apt-get install -y google-chrome-stable && \
    apt-get -y clean && \
    rm -rf /var/lib/apt/lists/*

WORKDIR /app
COPY main.py .

ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/chrome

google-chrome-stable でChromeをインストールしています。今回使用しているWebDriverのバージョンは101.0.4951.41ですが、将来、インストールしたChromeとのバージョンの違いで動作しない恐れがあります。

動作しない場合は、インストールされるChromeに適したWebDriverのバージョンを指定してください。

▼ こちらのサイトにChrome Driverのバージョンが管理されています。

ChromeDriver - WebDriver for Chrome - Downloads
Current Releases If you are using Chrome version 109, please download ChromeDriver 109.0.5414.25 If you are using Chrome version 108, please download ChromeDri...

pythonファイル

main.pyのソースコードは次の通りです。

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome import service as fs


CHROMEDRIVER = '/opt/chrome/chromedriver'
URL = '{スクレイピングするURLを記載}'

options = Options()
options.add_argument('--headless')  
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')

chrome_service = fs.Service(executable_path=CHROMEDRIVER) 
driver = webdriver.Chrome(service=chrome_service, options=options)
driver.get(URL)
html = driver.page_source
print(html)

コードの内容は、動的サイトのhtmlを出力する簡単なものです。

Chrome Driverは /opt/chrome/chromedriver に保存されるので、そのパスを指定しています。また、docker環境でchromeを起動させるのに必要なオプションを記載しています。

requirements.txt

今回使用したrequirements.txtの内容は次の通りです。

requests==2.27.1
selenium==4.1.5
chromedriver-binary==101.0.4951.41.0

chromedriver-binaryのバージョンは、dockerfileでインストールするChrome Driverのものと一致させておきます。

以上が使用したソースコード一式です。

Dockerイメージの作成

次のコマンドを実行して、Dockerイメージを作成します。

$ docker build -t web_scraping .

以下のようにdocker imageが作成されていれば完了です。

# Dockerイメージの確認
$ docker images

REPOSITORY      TAG       IMAGE ID       CREATED         SIZE
web_scraping    latest    xxxxxxxxxxxx   x seconds ago   929MB

Dockerコンテナに入って、実際にpythonが実行できるか確かめてみます。

# Dockerコンテナに入る
$ docker run -it --rm web_scraping /bin/bash
# コンテナ内でmain.pyを実行
root@xxxxxxxxxxxx:/app$ python main.py

# 出力
<html>
...
</html>

以上のように、Seleniumを使ったWebスクレイピング環境をDockerで構築することができました。

参考にした記事
タイトルとURLをコピーしました