はじめに
先日、WebスクレイピングでAzureポータルから情報を引いてくる案件がありました。当初windowsサーバ上でGUIを表示しつつスクレイピングしようとしたのですが、RDP切断後にスクレイバが動作しない問題があったため1、CentOSからヘッドレスブラウザでスクレイピングするようにしました。
ネット上には色々な情報があったのですが、それぞれをつまみ食いしないと動作しなかったため、必要な設定等をまとめておきます。
環境
- Docker version 1.7.1, build 786b29d/1.7.1
- CentOS Linux release 7.5.1804 (Core)
- Python 3.6.5
- selenium==3.14.0
今回スクレイパをpythonとseleniumで行いましたが、その他のバインディングでも同じようにできると思います。
手順
Chromeインストール
CentOSの標準リポジトリにChromeが存在しないため、Googleのリポジトリからダウンロードします。以下のrepoファイルを作成します2。
[google-chrome]
name=google-chrome
baseurl=http://dl.google.com/linux/chrome/rpm/stable/$basearch
enabled=1
gpgcheck=1
gpgkey=https://dl-ssl.google.com/linux/linux_signing_key.pub
yumでインストールします。この時、後述するchromedriverのバージョン選択に使用するため、yum infoでインストールするchromeのバージョンを確認しておく必要があります。
この例ではバージョン68をインストールします。
# yum info google-chrome-stable
(中略)
Name : google-chrome-stable
Arch : x86_64
Version : 68.0.3440.106
Release : 1
Size : 185 M
(中略)
# yum info install google-chrome-stable
chromedriverインストール
chromedriverの公式サイト3からchromedriverをダウンロードします。この時、インストールしたchromeをサポートしているバージョンをダウンロードします。今回の例ではバージョン68のChromeをインストールしたため、バージョン2.41のchromedriverをインストールします。
ちなみに、epelリポジトリにもchromedriverがありますが、バージョンが古く、stable版のchromeをサポートしていないため、動作しなくなります。
curl https://chromedriver.storage.googleapis.com/2.41/chromedriver_linux64.zip
unzip chromedriver_linux64.zip
cp -p chromedriver /usr/bin/
スクレイパからchromedriverにアクセスできることを確認しておいてください。PATHが通っているディレクトリが良いと思います。
スクレイパからChromeを起動
スクレイパからChromeを起動する際、--headless、--disable-gpu、--no-sandboxオプションをつけて起動します。
--headlessオプションでヘッドレスモードでChromeは起動するはずですが、--no-sandboxオプションを有効にしないとChromeがクラッシュします。ただ、いくつかのissueを確認したところ、コンテナ上で起動した場合に必要になるとの記載があるため、オンプレや仮想マシン上で動作させた場合不要かもしれません45。
--disable-gpuなしでもChromeは起動しますが、一部アクセラレーションが不具合を起こし表示が乱れる場合があるため、オプションを有効にしておいた方が良いでしょう。
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument('--headless')
options.add_argument('--disable-gpu')
options.add_argument('--no-sandbox')
driver = webdriver.Chrome(chrome_options=options)
driver.get("https://www.google.co.jp")
driver.quit()
-
詳しい友人に確認したところ、RDP切断後は内部的に画面がない状態になるため、GUIを使用するスクレイピングができないとのことでした。コンソールで実行しても、同一ユーザからリモート接続するとコンソールがログオフするため、同様の状態になります。 ↩
-
https://sites.google.com/a/chromium.org/chromedriver/downloads ↩
-
https://github.com/heroku/heroku-buildpack-google-chrome/issues/46 ↩