ChromiumをHeadlessにしてスクリーションショット画像を作成する
ChromiumでHeadless
最近、ChromeがHeadlessに対応しているという情報を目にしましたので備忘録として手順を共有したいと思います。
Amazon Linuxでやろうとしたけどツライ
最初にAmazon Linuxを使ってChromiumをインストールしようとしましたが、各種パッケージが足りないとエラーが続き諦めました。
Ubuntuでラクラクセットアップ
とても簡単にセットアップできましたのでこちらの方法をご紹介します。
まずはじめに適当なタイプのEC2インスタンスを起動します。サーバーの種類は、Ubuntu Server 16.04 LTS (HVM), SSD Volume Typeを選択しました。
次に、SSHでサーバーにアクセスを行い、以下の手順で必要なソフトウェアをインストールします。
$ sudo apt-get update $ sudo apt-get install chromium-browser -y $ sudo apt-get install fonts-ipafont-gothic fonts-ipafont-mincho -y $ chromium-browser --version Chromium 60.0.3112.113 Built on Ubuntu , running on Ubuntu 16.04
基本的にこれで終わりです。次に動作を確認します。
$ chromium-browser --headless --screenshot --window-size=1280,3000 https://dev.classmethod.jp/
結果として画像ファイルが保存されます。これをダウンロードして開くと以下のようになっていました。
期待通りの結果になりました!
Pythonから実行してみる
コマンドラインから実行できましたので、次にプログラムから実行してみたいと思います。まずは事前にライブラリ等をインストールします。
$ sudo apt-get install unzip $ sudo apt-get install libgconf2-4 $ sudo apt-get install python3-selenium $ wget https://chromedriver.storage.googleapis.com/2.32/chromedriver_linux64.zip $ unzip chromedriver_linux64.zip $ sudo mv chromedriver /usr/bin/ $ chromedriver --version ChromeDriver 2.32.498513 (2c63aa53b2c658de596ed550eb5267ec5967b351)
そして、Python3のコード例です。
#!/usr/bin/python3 import os from selenium import webdriver from selenium.webdriver.chrome.options import Options CHROME_BIN = "/usr/bin/chromium-browser" CHROME_DRIVER = os.path.expanduser('/usr/bin/chromedriver') options = Options() options.binary_location = CHROME_BIN options.add_argument('--headless') options.add_argument('--window-size=1280,3000') driver = webdriver.Chrome(CHROME_DRIVER, chrome_options=options) driver.get("https://dev.classmethod.jp") driver.save_screenshot("/tmp/devio.png") driver.quit()
以下コマンドを実行しました。ちゃんとスクリーンショットが保存されましたね。
$ python3 chromesample.py $ ls -la /tmp/devio.png -rw-rw-r-- 1 ubuntu ubuntu 962955 Sep 12 00:12 /tmp/devio.png
ブラウザのエラーを取得する
うまくスクリーンショットが取れましたので、ついでにWebサイトを読み込んだ時に発生したエラーを出力してみたいと思います。 先ほどのPythonコードに以下を追加するだけです。
for entry in driver.get_log('browser'): print(entry)
出力結果は以下のようになりました。なにやらファイルが見つからないエラーのようですね。
$ python3 chromesample.py {'timestamp': 1505176354710, 'source': 'network', 'level': 'SEVERE', 'message': 'https://eval.classmethod.jp/entry/ - Failed to load resource: the server responded with a status of 403 ()'} {'timestamp': 1505176354710, 'source': 'network', 'level': 'SEVERE', 'message': 'https://eval.classmethod.jp/entry/ - Failed to load resource: the server responded with a status of 403 ()'} {'timestamp': 1505176354710, 'source': 'network', 'level': 'SEVERE', 'message': 'https://eval.classmethod.jp/entry/ - Failed to load resource: the server responded with a status of 403 ()'}
まとめ
最近のChromium(Chrome)によって、ブラウザーのスクリーンショット作成を簡単に実現できるようになりました。今回はEC2に入れて試しましたが、複数のWebサイトのスクリーンショットを自動的に収集することを考えると、DockerやLambdaによるスケジュール実行や並列実行が良さそうですね。これらのやり方は別の機会にご紹介したいと思います。