昨日書いたんだけど、Kafkaを触ろうと思ってるんだよ?でも、触ろう触ろうと思ってると、違うものが目に入ってくるのであった。ということで
Headless Chromeで遊んでみた
Kafka一切関係なく、この記事を見かけたから。
Getting Started with Headless Chrome | Web | Google Developers
この辺のこともあるので、ちょっと見とこうかなって。
Phantom.jsのメンテナー、プロジェクトの将来に疑問を呈し、その座を降りる
ただ、今手元にある環境でごにょごにょするのもなんか嫌だなぁ・・・って思ったので、無駄にDockerに詰め込んでGebで遊んでみた。そして、そのせいで疲れた(ヽ´ω`)
できあがったものは
これ。
https://github.com/bufferings/sandbox-gebheadlesschrome
docker-composeで起動すると
$ docker-compose run app
Chrome(beta)とChromeDriverとGroovyがインストールされた状態で、インタラクティブモードで起動する。
root@4013e872287a:/geb# google-chrome --version Google Chrome 59.0.3071.29 beta root@4013e872287a:/geb# chromedriver --version ChromeDriver 2.29.461571 (8a88bbe0775e2a23afda0ceaf2ef7ee74e822cc5) root@4013e872287a:/geb# groovy --version Groovy Version: 2.4.11 JVM: 1.8.0_131 Vendor: Oracle Corporation OS: Linux
Chromeを動かしてみる
これで動くかな?と思って、試しに叩いてみたらエラーになった。
# google-chrome --headless
ので、エラーメッセージからぐぐって、
dockerでGUIのアプリを使用する(chromium) | ぴあっこ作業日誌 を参考にして --no-sandbox
をつけてみた。Dockerで実行してることが原因みたいね。
# google-chrome --headless --no-sandbox
一歩進んだけど、まだエラーが出るので Getting Started with Headless Chrome | Web | Google Developers をもういちど良く見てみたら、途中の例には書いてないけど、最初の方に --disable-gpu
が今は必要って書いてあった
# google-chrome --headless --no-sandbox --disable-gpu
(∩´∀`)∩ワーイエラー消えた。
キャプチャとってみる
Getting Started with Headless Chrome | Web | Google Developers のサンプルに --no-sandbox --disable-gpu
をつけて実行
# google-chrome --headless --no-sandbox --disable-gpu \ --screenshot --window-size=412,732 https://www.chromestatus.com/
したらscreenshot.pngってファイルが作られてた(rootの600だったので666にした)。
あら・・・。
もう一回実行したら撮れた。撮れるときと先走るときがあるみたいね。
Gebで実行
Groovy入れといたのはGebで実行してみようかなと思って。なので、Geb動作確認用のファイルも置いといた。実行するとGebがHeadless Chromeを使って、 Googleのホームページを開いてキャプチャとる。そんな感じ。初回実行時は依存ライブラリーをとりにいくのでしばらく待たされる。
# groovy Hello
Gebからの画面キャプチャは、フォントが入ってないからこんなんだけど。撮れた。
Chromeのキャプチャ
ヘッドレスかどうかに関係なく、Chromeのキャプチャは見えてる範囲だけみたいよね。
↓のサイトに「こんな風にして全画面キャプチャーツールとして使えるよ」ってあるけどよく分かってない。
Using headless Chrome as an automated screenshot tool
僕の作ったDockerfileの注意点
キャプチャーとかの出力ファイルがrootで作られるので、ホスト側から触るときにちょっとめんどくさい。
これ以降はたぶん全く忘れてるであろう1年後の自分への解説。
SDKMAN!
SDKMAN! the Software Development Kit Manager
を使って、JDKとGroovyを入れた。全然知らなかったんだけど簡単だったよ。
# Java & Groovy RUN curl -s "https://get.sdkman.io" | bash \ && echo "gvm_auto_answer=true" >> ~/.sdkman/etc/config \ && /bin/bash -c "source /root/.sdkman/bin/sdkman-init.sh && sdk install java && sdk install groovy"
Chrome
この辺を参考にしてHeadlessに対応してるベータ版を入れた。
https://github.com/ebidel/lighthouse-ci/blob/master/builder/Dockerfile
# Chrome RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add - \ && sh -c 'echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list' \ && apt-get update \ && apt-get install -y google-chrome-beta
ChromeDriver
ここを参考にして入れた。
docker-chromedriver/Dockerfile at master · RobCherry/docker-chromedriver · GitHub
# ChromeDriver RUN CHROMEDRIVER_VERSION=`curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE` \ && mkdir -p /opt/chromedriver-$CHROMEDRIVER_VERSION \ && curl -sS -o /tmp/chromedriver_linux64.zip http://chromedriver.storage.googleapis.com/$CHROMEDRIVER_VERSION/chromedriver_linux64.zip \ && unzip -qq /tmp/chromedriver_linux64.zip -d /opt/chromedriver-$CHROMEDRIVER_VERSION \ && rm /tmp/chromedriver_linux64.zip \ && chmod +x /opt/chromedriver-$CHROMEDRIVER_VERSION/chromedriver \ && ln -fs /opt/chromedriver-$CHROMEDRIVER_VERSION/chromedriver /usr/local/bin/chromedriver
Grape
Gebを試しに動かしてみるのにGrapeってGroovyの依存管理機能を初めて使ってみた。CLOVERを読みながらやってみた。
Groovyの簡易依存関係管理ツール、Grapeを使ってみる - CLOVER
@Grapes([ @Grab("org.gebish:geb-core:1.1.1"), @Grab("org.seleniumhq.selenium:selenium-chrome-driver:3.4.0"), @Grab("org.seleniumhq.selenium:selenium-support:3.4.0") ]) import geb.Browser Browser.drive { go "https://google.com/" report "sample" }.quit()
Grapeがライブラリを置いておくディレクトリ(~/.groovy/grapes)は、ボリュームマウントしておくことにした。2回目以降取りに行かなくていいように。
Geb
この部分は
Browser.drive { go "https://google.com/" report "sample" }.quit()
Googleのホームページを開いて(go)、"sample"って名前でキャプチャ(htmlとpng)を取って(report)、ブラウザを閉じる(quit)。ってことね。
GebConfig
んで、今回のメインのGebConfigだけどオプションを3つ指定して起動してるだけ。
import org.openqa.selenium.chrome.ChromeDriver import org.openqa.selenium.remote.DesiredCapabilities import org.openqa.selenium.chrome.ChromeOptions reportsDir = "target" driver = { ChromeOptions options = new ChromeOptions() options.addArguments("--headless", "--no-sandbox", "--disable-gpu") DesiredCapabilities capabilities = DesiredCapabilities.chrome() capabilities.setCapability(ChromeOptions.CAPABILITY, options) new ChromeDriver(capabilities) }
docker-compose
は、マウントとか指定するのが面倒だったから書いただけ。
version: '3' services: app: build: . working_dir: "/geb" volumes: - ./geb:/geb - ./grapes:/root/.groovy/grapes
面白かった
Dockerじゃなかったらあっさりしてたと思う。おしまい。
2017-05-04 追記
あー。そういえば--headlessつけずに実行したらどうなるのか確認しようと思って忘れてた。また後で確認しとこっと。餃子包まなきゃ。
— Mitsuyuki Shiiba (@bufferings) 2017年5月3日
やっぱり動かんかった。
root@42dbeb2a9909:/geb# google-chrome --no-sandbox --disable-gpu --screenshot --window-size=412,732 https://www.chromestatus.com/ root@42dbeb2a9909:/geb# [0503/235453.940351:ERROR:nacl_helper_linux.cc(311)] NaCl helper process running without a sandbox! Most likely you need to configure your SUID sandbox correctly
Gebの方はこんな感じになった。
Caused by: org.openqa.selenium.WebDriverException: unknown error: Chrome failed to start: exited abnormally (Driver info: chromedriver=2.29.461571 (8a88bbe0775e2a23afda0ceaf2ef7ee74e822cc5),platform=Linux 4.8.0-49-generic x86_64) (WARNING: The server did not provide any stacktrace information)