機械学習の学習データをスクレイピングをするためのコンテナを構築したのでその手順を書きました。
JavaScriptのページをスクレイピングする場合は、SplashかSeleniumを使用して下さい。
環境構築
環境破棄・操作
ディレクトリを作成
Docker Composeを配置するディレクトリを作成します。
作成したディレクトリ名がDocker Composeのプロジェクト名となり、ネットワーク名とボリューム名の先頭文字として設定されます。
% mkdir my_scraping
% cd my_scraping
データベースの認証情報を設定
PostgreSQLコンテナのデータベースの認証情報の環境変数を.env
に設定します。
環境変数を作成
docker-compose.yml
を作成するディレクトリと同じ場所に作成します。
% vi .env
.env
POSTGRES_DB=postgresdb
POSTGRES_USER=postgresuser
POSTGRES_PASSWORD=postgrespass
複数の.env
を作成した場合、個々の.env
に同名の環境変数名を設定すると競合してしまうので、必ず一意の環境変数名を付けるようにしてください。
docker-compose.yml
が配置されているディレクトリ内に.env
を作成すると、Docker Compose実行時に自動的に.env
の内容が読み込まれます。
Docker Composeを構築
Docker Composeの設定ファイルであるdocker-compose.yml
を作成し、同時起動させる下記コンテナの起動設定を行います。
ベースイメージ
- Python – Official Image | Docker Hub(カスタムイメージのベースイメージ)
- scrapy-plugins/scrapy-splash: Scrapy+Splash for JavaScript integration(オフィシャルイメージ)
- Postgres – Official Image | Docker Hub(オフィシャルイメージ)
% vi docker-compose.yml
docker-compose.yml
version: '3.9'
services:
postgresql:
image: postgres:14.1-bullseye
container_name: my_postgresql
networks:
- net
ports:
- 5432:5432
volumes:
- db_volume:/var/lib/postgresql/data
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
splash:
depends_on:
- postgresql
image: scrapinghub/splash:3.5
container_name: my_splash
networks:
- net
ports:
- 8050:8050
scrapy:
depends_on:
- splash
build:
context: .
dockerfile: Dockerfile
image: scrapy:2.6.1
container_name: my_scrapy
networks:
- net
volumes:
- $PWD/app:/usr/src/app
tty: true
networks:
net:
volumes:
db_volume:
ComposeFileの設定を確認
% docker-compose config
networks:
net: {}
services:
postgresql:
container_name: my_postgresql
environment:
POSTGRES_DB: postgresdb
POSTGRES_PASSWORD: postgrespass
POSTGRES_USER: postgresuser
image: postgres:14.1-bullseye
networks:
net: null
ports:
- published: 5432
target: 5432
volumes:
- db_volume:/var/lib/postgresql/data:rw
scrapy:
build:
context: /Users/my_scraping
dockerfile: Dockerfile
container_name: my_scrapy
depends_on:
splash:
condition: service_started
image: scrapy:2.6.1
networks:
net: null
tty: true
volumes:
- /Users/my_scraping/app:/usr/src/app:rw
splash:
container_name: my_splash
depends_on:
postgresql:
condition: service_started
image: scrapinghub/splash:3.5
networks:
net: null
ports:
- published: 8050
target: 8050
version: '3.9'
volumes:
db_volume: {}
カスタムイメージを作成
ベースイメージのPythonイメージに、Dockerfile
に記載した設定でカスタマイズしたScrapyイメージを作成します。
Dockerfile
にはSeleniumで使用するGoogle ChromeとChromeドライバーのインストール、requirements.txt
で指定したパッケージをpip
でインストールする処理を記述しています。
Dockerfileを作成
docker-compose.yml
と同じディレクトリ内に作成します。
% vi Dockerfile
Dockerfile
FROM python:3.8.12-bullseye
WORKDIR /usr/src/app
RUN apt-get update && apt-get install -y unzip
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
ADD https://chromedriver.storage.googleapis.com/99.0.4844.51/chromedriver_linux64.zip /opt/chrome/
RUN cd /opt/chrome/ && \
unzip chromedriver_linux64.zip
ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/chrome
COPY requirements.txt ./
RUN pip install --upgrade pip && pip install --no-cache-dir -r ./requirements.txt
カスタムイメージにインストールするパッケージを指定
イメージ作成時にインストールするパッケージをrequirements.txt
に指定します。指定するパッケージは下記になります。
- Scrapy:スクレイピング・クローリングをするフレームワーク
- Scrapy-Splash:ScrapyでJavaScriptをスクレイピングするライブラリ(Splashサーバーに接続して使う)
- Selenium:JavaScriptをスクレイピングするライブラリ
- python-dotenv:Pythonで環境変数を扱うライブラリ
- psycopg2:PythonでPostgreSQLを扱うライブラリ
docker-compose.yml
と同じディレクトリ内に作成します。
% vi requirements.txt
requirements.txt
scrapy==2.6.1
scrapy-splash==0.8.0
selenium==4.1.3
python-dotenv==0.19.2
psycopg2==2.9.3
コンテナを起動
イメージをビルドしてすべてのコンテナを起動します。
docker-compose.yml
が置かれているディレクトリ上で実行します。
% docker-compose up -d --build
Creating network "my_scraping_net" with the default driver
Creating volume "my_scraping_db_volume" with default driver
Building scrapy
[+] Building 28.8s (14/14) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 831B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/python:3.8.12-bullseye 2.1s
=> [1/8] FROM docker.io/library/python:3.8.12-bullseye@sha256:53cb515206 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 271B 0.0s
=> https://chromedriver.storage.googleapis.com/99.0.4844.51/chromedriver 0.1s
=> CACHED [2/8] WORKDIR /usr/src/app 0.0s
=> CACHED [3/8] RUN apt-get update && apt-get install -y unzip 0.0s
=> CACHED [4/8] RUN wget -q -O - https://dl-ssl.google.com/linux/linux_s 0.0s
=> CACHED [5/8] ADD https://chromedriver.storage.googleapis.com/99.0.484 0.0s
=> CACHED [6/8] RUN cd /opt/chrome/ && unzip chromedriver_linux64.zi 0.0s
=> [7/8] COPY requirements.txt ./ 0.0s
=> [8/8] RUN pip install --upgrade pip && pip install --no-cache-dir -r 25.3s
=> exporting to image 1.1s
=> => exporting layers 1.1s
=> => writing image sha256:5f87d975817d1590cb720221ea293d24c0d560dd2d4b2 0.0s
=> => naming to docker.io/library/scrapy:2.6.1 0.0s
Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
Creating my_postgresql ... done
Creating my_splash ... done
Creating my_scrapy ... done
稼働中のコンテナを確認
% docker-compose ps
Name Command State Ports
-------------------------------------------------------------------------------
my_postgresql docker-entrypoint.sh postgres Up 0.0.0.0:5432->5432/tcp
my_scrapy python3 Up
my_splash python3 /app/bin/splash -- ... Up 0.0.0.0:8050->8050/tcp
イメージを確認
% docker-compose images
Container Repository Tag Image Id Size
----------------------------------------------------------------------------
my_postgresql postgres 14.1-bullseye da2cb49d7a8d 374 MB
my_scrapy scrapy 2.6.1 c4bb14565272 1.623 GB
my_splash scrapinghub/splash 3.5 93cac3cba2d3 1.888 GB
ネットワークを確認
% docker network ls
NETWORK ID NAME DRIVER SCOPE
4a133cbc34e8 bridge bridge local
69b09e935fcd host host local
b9591855ac06 my_scraping_net bridge local
f70f9b9aa9f8 none null local
ボリュームを確認
% docker volume ls
DRIVER VOLUME NAME
local my_scraping_db_volume
コンテナに入る
docker-compose.ymlに設定されている サービス名を指定してコンテナに入ります。
% docker-compose exec scrapy bash
Chromeを確認
# google-chrome -version
Google Chrome 99.0.4844.74
ChromeDriverを確認
# chromedriver --version
ChromeDriver 99.0.4844.51 (d537ec02474b5afe23684e7963d538896c63ac77-refs/branch-heads/4844@{#875})
ChromeとChromeDriverは同じバージョンで組み合わせないと動作しないので、それぞれに適切なバージョンをインストールしてください。
- 例えばChromeのバージョンが
99.xxx
なら 、ChromeDriverのバージョンも99.xxx
に合わせてください。
データベースを確認
ユーザー名とデータベース名を別の名前に変更した場合はユーザー名と同名のデータベースは作成されず、ユーザー名だけではログインできないので、ユーザー名とデータベース名を一緒に指定してログインしてください。
% docker-compose exec postgresql psql -U postgresuser postgresdb
psql (14.1 (Debian 14.1-1.pgdg110+1))
Type "help" for help.
# l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access p
rivileges
------------+--------------+----------+------------+------------+---------------
----------------
postgres | postgresuser | UTF8 | en_US.utf8 | en_US.utf8 |
postgresdb | postgresuser | UTF8 | en_US.utf8 | en_US.utf8 |
template0 | postgresuser | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgresuse
r +
| | | | | postgresuser=C
Tc/postgresuser
template1 | postgresuser | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgresuse
r +
| | | | | postgresuser=C
Tc/postgresuser
(4 rows)
Splashを設定
Scrapyプロジェクトを作成
app
ディレクトリが無い場合はDocker Compose起動時に自動生成されます。
# cd app
# scrapy startproject my_project
# scrapy genspider my_project example.com
Created spider 'my_project' using template 'basic'
# cd my_project/my_project
# scrapy genspider my_spider example.com
Created spider 'my_spider' using template 'basic' in module:
my_project.spiders.my_spider
settings.pyにSplashの設定を追加
SPIDER_MIDDLEWARES = {
'scrapy_splash.SplashDeduplicateArgsMiddleware': 100,
}
DOWNLOADER_MIDDLEWARES = {
'scrapy_splash.SplashCookiesMiddleware': 723,
'scrapy_splash.SplashMiddleware': 725,
'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810,
}
SPLASH_URL = 'http://splash:8050'
DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter'
HTTPCACHE_STORAGE = 'scrapy_splash.SplashAwareFSCacheStorage'
Docker ComposeではDockerネットワークが作成され、サービス名をホスト名としてコンテナ間でアクセスすることができるため、http://splash:8050
でScrapyコンテナからSplashコンテナにアクセスすることができます。
すべてのコンテナを破棄
すべてのコンテナが破棄され、ネットワークも破棄されますが、イメージとボリュームは残ります。
% docker-compose down
Stopping my_scrapy ... done
Stopping my_splash ... done
Stopping my_postgresql ... done
Removing my_scrapy ... done
すべてのイメージを削除
イメージを確認
% docker-compose images
Container Repository Tag Image Id Size
----------------------------------------------------------------------------
my_postgresql postgres 14.1-bullseye da2cb49d7a8d 374 MB
my_scrapy scrapy 2.6.1 c4bb14565272 1.623 GB
my_splash scrapinghub/splash 3.5 93cac3cba2d3 1.888 GB
イメージを削除
% docker rmi c4bb14565272 da2cb49d7a8d 93cac3cba2d3
Untagged: scrapy:2.6.1
Deleted: sha256:c4bb14565272cce160cce9231b87c719227460160fbe80758d8d58687f3c0246
Untagged: postgres:14.1-bullseye
Untagged: postgres@sha256:3162a6ead070474b27289f09eac4c865e75f93847a2d7098f718ee5a721637c4
Deleted: sha256:da2cb49d7a8d1416cfc2ec6fb47b60112b3a2f276bcf7439ef18e7c505b83fc6
Deleted: sha256:3795b5d9b02f6ed378c29aac7f63cc955e48116f30bdc12bea9f02d47ac17b71
Deleted: sha256:d9cf9b69fade01903aee2e9d3d79be9283b15d928c6abf09cf094bd2fcf04b34
Deleted: sha256:e255c198c90fdf9ea2670f2da636b070f9ab79456118029a4c66e7f965ef835d
Deleted: sha256:15ef1d65041e3a265de67365a7e426a66a5b49e174b3dcfbb709e689f23530fe
Deleted: sha256:25a012251e866e7fbeb177d221b598d1eb4908446c3a79b9a2d7b3db243829a6
Deleted: sha256:7bff8e0a47f8f8c36996e7870c0fc26f79ddbbc4df0ce1e87bbaad2b921f1dc3
Deleted: sha256:52bd960d6ad2eea8e806acbf4f7d548cffd23620c5e6b4e2f1ed137b40ecf2c4
Deleted: sha256:9d9057073e73e8603debcc13e62f285ad68fa2c012ac140313c3e389c747b6d8
Deleted: sha256:b3af311bc5a72ad1a3aaae8eda53013616cea637603c1706078fd4cb07804b98
Deleted: sha256:9418cfad81731d3b3cbc99d29eaf02bc3a041eeb9edf90199f278ed03dd2f65b
Deleted: sha256:c6a68b552b98db291efc74024707c5eaa2337b7870fbfe4bb2ee631a6db3a43e
Deleted: sha256:91b43708591e86683a3868c8787c00512250ec1766d74b054db24b4746883b0b
Deleted: sha256:7d0ebbe3f5d26c1b5ec4d5dbb6fe3205d7061f9735080b0162d550530328abd6
Untagged: scrapinghub/splash:3.5
Untagged: scrapinghub/splash@sha256:c8f1036efd24dff8a688d5ccfcc4378120c447274caa832f090d9864d0bb598f
Deleted: sha256:93cac3cba2d3e2ffec01aaf317835498deee26259dd8f74ea97d22491247a5d4
Deleted: sha256:a314ef7a76396b490568c659f2c9711692dd7b350df8928f4b57ff3aa0227ac7
Deleted: sha256:2c1ee1f3fb3d801c51a744489c40e9897a19533fbd0ad46e460974a325ae1d88
Deleted: sha256:a19c0aa88e7fb877e3642c552cbd345f7ce6899acd350a655eb447d80dbdad35
Deleted: sha256:1ce9af445dedd12fffab01989bd3a3ff81ff8f41dd56511f7b4fc9c21c5e57c7
Deleted: sha256:37b2a3647011fd577ef0caa868b79f01d8c987e796b35a969d985799f7b149ab
Deleted: sha256:1fdc945756ddcb75e565dd0fb4f35fea39f07061a2f0128acc4b86381b55daf6
Deleted: sha256:8a50f368d132f50c272b7c3d0a88b81ab0dccb332d7954658b6caa23cd0dab3d
Deleted: sha256:e7f3b8ff98bb5a70f3e8049f23b1ad33d09fad6720046fd07873f5b2fe192152
Deleted: sha256:78b456e877dedddeeea89b402ad4dc30be663d5b2e852d38efd2bdc1f057d4a4
Deleted: sha256:dc73b9e1bf453db497f1dded1f1effb05944f244887243a27b687ed76b7c0c32
Deleted: sha256:a6a2a2b169c98ed4d887d4830d0f9f8c229784f3260465d312819e1385fb7504
Deleted: sha256:0878c576667efa863d30c60f8093c9411418249e5bf220a15801668604958f5a
Deleted: sha256:fb40c8cad6920f8e2c03cb24730201d3f3ddec9c612ba8c3dd556a720ef9b027
Deleted: sha256:f9052a79fb53c80f811c3824cf9de046f45dcf7b2762ab0f87d1dd8fb697a3d5
Deleted: sha256:2121c2630e0dcfc590ac186cd13328d34ca4253fd0cfc2d1c6e0901c8fd8e8e8
Deleted: sha256:1f8beba7e5f0a447e70d43e6bf371ccc20cbbb89888f03734fecaadf81c94bb9
Deleted: sha256:de24b0a7f0fd3790d5e158ee70fe72467f6b67c43ac2d6cb8e38843601463004
Deleted: sha256:83ff38e178cdf701f61a041c4948b6639a37e976201e7e47ac0fba4d96d5d640
Deleted: sha256:55c47d04539b7ef70aea066de6ab076f15062dd96238f97072aad99bef7e0913
Deleted: sha256:1e5d5ef34c270ec5a9d24b7a60a53d9bf71c835c22000acf1bb3b915befe3519
Deleted: sha256:39dbebdb3c89237b38501ae2d4b7a8e85576e8d1b1407abba66b90899a8aab4f
Deleted: sha256:6a51f500a462f053f5b68cbde550ae052c863b88101cfd69c9b6db0ce388dfd7
Deleted: sha256:28a6cdeed6dd92b5eec9b21b71b0ff3e93754313adc77ce5f2288b4e59e53568
Deleted: sha256:48ba0c6fdf4b069aad7a1eb6299dee017ef75b929a87ed63bc9226dee2cd50e8
Deleted: sha256:4d5330c8d5056fdfb6f2e32b225452de71517794a80e3ef998440e184d2e80cb
Deleted: sha256:3a9fa6b9e7ae21b704ed61109b612970f2b21449cd53e3154ed8800e2aefee0d
Deleted: sha256:7ef3687765828a9cb2645925f27febbac21a5adece69e8437c26184a897b6ec7
ボリュームを削除
ボリュームを確認
% docker volume ls
DRIVER VOLUME NAME
local my_scraping_db_volume
ボリュームを削除
% docker volume rm my_scraping_db_volume
my_scraping_db_volume
ボリュームを削除するとボリューム内のデータベースも削除されるので、データベースを保持する場合はボリュームのバックアップをとってから削除してください。
データベースの認証情報を変更
データベースの認証情報はボリューム内に保存されているので、認証情報を変更する場合は下記のいずれかの方法で変更してください。
- PostgreSQLコンテナ内に入り、データベースの認証情報を
.env
内で変更したものと同じものに変更する。 - ボリュームを削除し、
.env
内の認証情報を変更後Docker Composeを再度ビルドして変更する。
参考
Docker
- さわって学ぶクラウドインフラ docker基礎からのコンテナ構築
- とりあえず Docker で PostgreSQL を動かす手順 – Qiita
- 公式Dockerイメージ PostgreSQL メモ – Qiita
- Docker/Postgresでpassword authentication failedが出た場合の対処法 – Qiita
- Docker image(イメージ)の違い:alpine,bullseye, buster, slim, stretch, jessie, slim-buster, windowsservercore, latestどれを選ぶべきか?
- CentOS、UbuntuなどLinux OSのバージョン確認をするコマンド | UX MILK
- docker-compose.ymlでDockerfileを指定したい – Qiita
- docker-compose.ymlのbuild設定はとりあえずcontextもdockerfileも埋めとけって話 – Qiita
- Docker Composeの環境変数ではなくsecretsで秘密情報を扱う – Qiita
- ファイルの指定した行のみ表示する – Qiita
- docker-compose
up
とかbuild
とかstart
とかの違いを理解できていなかったのでまとめてみた – Qiita - 【Docker For Mac】Error response from daemon: Mounts deniedの対応 – Qiita
- DockerfileのCMDおよびdocker-compose.ymlで複数のbashコマンドを実行させる方法 – Qiita
- docker-composeでコンテナが起動しない – inamuu.com
- docker-compose で exit with status 0 の解決法
- docker-compose.ymlで.envファイルに定義した環境変数を使う – lycheejam’s tech log
- docker-composeとネットワーク、コンテナのホスト名の割り当てなどを理解する – Qiita
- Docker volumeの削除 – Qiita
- Dockerイメージとコンテナの削除方法 – Qiita
- docker-composeで作成されるものの名前を明示的に指定する方法 – Qiita
Python
Scrapy
- Pythonクローリング&スクレイピング[増補改訂版] -データ収集・解析のための実践開発ガイド
- Python, scrapy でお祭りスクレイピング – Qiita
- 図解!Python Scrapyの使い方を徹底解説!(サンプルコード付きチュートリアル) – AI-interのPython3入門
- 【Scrapy】インストール→スパイダー実行まで操作手順メモ – ゆうきのせかい
- Python, Scrapyの使い方(Webクローリング、スクレイピング) | note.nkmk.me
- 10分で理解する Scrapy – Qiita
Splash
- Splash – A javascript rendering service — Splash 3.5 documentation
- CentOS7でscrapy-splashを使ってJavaScriptの解析(Scrapy その3) – 株式会社CoLabMix
- jsサイトをスクレイピングするなら、seleniumよりsplash! – Qiita
- 第12章 ScrapyとJavaScript – Scrapy Note
- ScrapyとSplashでJavascriptをハンドリングする – nullpo.io
- docker-compoesでpython(scrapy / splash)のスクレイピング環境構築 | Tech Memo
Selenium
- Docker上で、Python + Selenium + Headless Chromeを使用してWEBスクレイピング – 趣味で書いているプログラムの備忘録
- ChromeDriver – WebDriver for Chrome
PostgreSQL
人気記事
まだデータがありません。
ニューラルネットワークのフォワードプロパゲーションを実装してみた|ITエンジニアとして経験・学習したこと
"[…] なお、フォワードプロパゲーションについては、以下のサイトを参照のこと。 https://hossuii.com/?p=1803 […] "