【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のバージョンが管理されています。

Downloads  |  ChromeDriver  |  Chrome for Developers

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をコピーしました