動機
Raspberry piの小型低電力の特性を生かした活用方法の一つとして、headlessブラウザを使った自動化環境にチャレンジして見たいと思います。
一昔前だと、VXFD仮想ディスプレイ+pyvirtualdisplayの環境で、ブラウザにiceweasel(現:Firefox)を使って実現していたようで、その辺りの記事はよく見かけます。
今回、Chromeに実装されたheadlessモードを使ってやってみました。
とはいえ、情報が少なく試行錯誤の連続でしたが、しばらくやってから冷静に考えると結構簡単に解決したので手順も含めて共有します。
試行錯誤履歴
- Firefox + VXFD + pyvirtualdisplay環境
- VXFDはブラウザ標準のheadlessではないので、やり方だけググって見送り
- Firefoxでのheadless
-
apt-get
で取得できるFirefoxバージョンが52で、まだ-headless
に対応していない - しかも、GeckoDriverは64bit対応版しか公開されておらず、32bitモードで動くraspberry piでは扱えず
-
- Chromium-browser + ChromeDriverの組み合わせ
- ChromeDriverをdebianのパッケージレポジトリから探したが、GeckoDriverと同じく64bit版しか見つからず断念
行き着いた先
色々試して路頭に迷っていたところ、ふとapt
でChromeDriveがあるんじゃね?と思って探すとあったんですね。灯台下暗しと言いますか・・・
chromium-browserがaptで取得できるのだから当たり前といえば当たり前なんでしょうが、取り組み当初は思いつきませんでした。ちゃんと全体を見渡してから一つずつ試さないとダメですね。
さて、気を取り直して以下、環境構築手順とサンプルプログラム。
最終的な環境
- Raspberry pi3
- Raspbian Stretch lite
- Chromium v65
- ChromeDriver v2.35
- Python2.7
- Selene
## 環境構築
Chrome, ChromeDriverのインストールと設定
# chromeブラウザインストール(2018.7.10時点でv65)
$ sudo apt-get install chromium-browser
# v65のChromeに対応したChromeDriveをインストール
$ sudo apt-get install chromium-chromedriver
# chromedriverが環境パス上に無いので、/usr/bin/下にシンボリックリンクを張っておく。
# コードでパスを指定するので別にやらなくても良い。
$ sudo ln -s /usr/lib/chromium-browser/chromedriver /usr/bin/
# 日本語フォントが無いのでインストール
$ sudo apt-get install fonts-ipafont-gothic fonts-ipafont-mincho
インストールしたバージョンは下記。
$ chromium-browser --version
Chromium 65.0.3325.181 Built on Raspbian , running on Raspbian 9.4
$ chromedriver --version
ChromeDriver 2.35 (0)
seleneインストール
Javaでよく使われるSeleniumラッパーでSelenideというものがありますが、それをPython向けにポートしたSeleneというのがあります。
Seleniumの面倒なところを吸収してくれているのでオススメのライブラリです。
下記の手順でpipを使ってインストールします。
$ sudo apt-get install python-pip
$ pip install selene --pre
サンプルプログラム(python)
from selene.browsers import BrowserName
from selene.api import *
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
import traceback
def main():
try:
config.browser_name = BrowserName.CHROME
chrome_option = webdriver.ChromeOptions()
chrome_option.add_argument('--headless')
chrome_option.add_argument('--disable-gpu')
driver = webdriver.Chrome(executable_path="/usr/bin/chromedriver", chrome_options=chrome_option)
browser.set_driver(driver)
browser.open_url("http://www.yahoo.co.jp")
driver.save_screenshot('screenshot.png')
browser.quit()
except:
print traceback.format_exc()
browser.quit()
if __name__ == '__main__':
main()
最後に
このサンプルプログラムを実行すると、実行フォルダにscreenshot.png
が作成されます。
ここまでできればSeleniumの要領でページ操作をすれば色々とできそうです。
まだ複雑なJavascriptが存在するようなページ操作などは試せていませんが、Chrome v65なので問題になるケースは少ないのではないかと思っています。
実行速度も比較検証はしていませんが、時間的にシビアな処理をさせるつもりも無いので特に問題ないでしょう。
このくらいであればRaspberry pi Zeroでも動くかもしれませんが、いずれチャレンジしてみようと思います。どなたかすでに試された方がいれば共有してくれると嬉しいです。