uzullaがブログ

uzullaがブログです。

Raspberry pi zero wでウェブサイトのスクショを取るその2(phantomjs+selenium+python)

一つ前の記事で、firefoxめっちゃ重くて駄目だったのでphantomjsを使う場合の話。

ページの大きさにもよるけど、なつかしさあふれるphantomjsはさすがに速い。軽いページなら10秒以下でうごく。

このブログも(表示はモバイル用?になってしまうけど)頑張れば一応レンダリング完了できる。

phantomjsをいれる

$ apt install phantomjs

トラブルシュート

本来上でphantomjsがはいると思うんだけれど、うまくうごかなかった。

$ /usr/bin/phantomjs --version
$ echo $?
1

バージョンがでてこないし、ステータスコードは0じゃないし、seleniumからも操作できないし※、なんかおかしいので以下から野良blobをDLしていれました。みなさんはちゃんとやろう。

*1

GitHub - aeberhardo/phantomjs-linux-armv6l: PhantomJS compiled on a Raspberry PI (Raspbian "wheezy").

$ wget https://github.com/aeberhardo/phantomjs-linux-armv6l/archive/master.zip
$ unzip master.zip
$ cd phantomjs-linux-armv6l-master/
$ tar xvjf phantomjs-1.9.0-linux-armv6l.tar.bz2
$ cd phantomjs-1.9.0-linux-armv6l/bin
$ sudo cp phantomjs /usr/local/bin/phantomjs
$ phantomjs --version
1.9.0
$ which phantomjs
/usr/local/bin/phantomjs

selenium.common.exceptions.WebDriverException: Message: Service /usr/bin/phantomjs unexpectedly exited.

PythonseleniumのLibをいれる

$ python -m pip install selenium

コードを書く

pjs_ss.py

#!python
from selenium import webdriver

driver = webdriver.PhantomJS(executable_path='/usr/local/bin/phantomjs', service_args=['--ignore-ssl-errors=true', '--ssl-protocol=any'])
driver.get("http://www.yahoo.co.jp/")
driver.save_screenshot("test.png")

driver.quit()
print("done")

※ めっちゃSSLエラー無視する指定してますが、皆さんはちゃんとしてください。

実行

$ python3.6 pjs_ss.py
/usr/local/lib/python3.6/site-packages/selenium/webdriver/phantomjs/webdriver.py:49: UserWarning: Selenium support for PhantomJS has been deprecated, please use headless versions of Chrome or Firefox instead
  warnings.warn('Selenium support for PhantomJS has been deprecated, please use headless '
done
$

test.pngが保存されていれば成功。

実行時にめっちゃWARNいわれますけど、そうはいうてもARMv6のRaspi zero向けにheadlessをサポートするバージョンのchromiumがないし(ビルドがどう考えても大変)、firefoxはめっちゃ遅かったんや…。

ただ、phantomjsはどうしてもWeb 1.0風のなつかしさあふれるページになりますね。(個人的にはこれで十分なのだが、UA設定したりすればもうちょっとマシになるのかね?)

まとめ

しょぼいサイトならphantomjsでなんとかなりそう、ただまあRaspberry pi zero w みたいな非力な環境でがんばるより、スクショを取れる公開Web APIを使ったほうが良い。

完全にラズパイ素人なので甘く見ていたのだけれど、ARMv6(Pi0とか)とARMv8(Pi 3Bとか)の溝はかなり深くて広い…、そしてARMv6はサポートしないよってかいてあるOSS多すぎウケるww。かといってPi 3B電気食い過ぎでしょ…。

こちらからは以上です。

余談

最近のchromium-browserのARMバイナリを配布しているところをみつけておとしてみたけど、Illegal instructionで動かず。

Packages in “Chromium dev” : Chromium dev : “Chromium team” team

$ readelf -a /usr/lib/chromium-browser/chromium-browser > txt
$ less txt
〜〜かなり後ろ〜〜
File Attributes
  Tag_CPU_name: "7-A"
  Tag_CPU_arch: v7

ウーン、v7以降ね…。

なおfirefox

File Attributes
  Tag_CPU_name: "6"
  Tag_CPU_arch: v6

勿論動いた。

まあ、chromiumをがんばってビルドする記事は結構みつかるんだけど、ARMとかいてあるけどそれv7の話だよね???というエントリしかみつからなかった。ARMv6でv59以降のchromiumをビルドするすべを募集中です…。

*1:phantomjs のバージョンの問題かもしれないとおもったけど、--versionうごかないのはさすがに??

Raspberry pi zero wでウェブサイトのスクショを取る(firefox+selenium+python)

現在GW真っ只中の深夜4時半ですが、管理しているサーバーの一つからアラートがとんできておこされたuzullaですこんばんわ。

再起動をかけてみたけどかえってこないので、サーバー業者に問い合わせをして今にいたります。ファイルシステムがぶっこわれている気がします、こまりますね。

さて本題

raspberry pi zero wで、あるウェブサイトのスクショ画像を作成したいのですが、どうやるべきか。

最近だとchrome にheadlessモードが追加されてそれをつかうのがベターだとおもうのですが、raspberry pi zero w にはまだv59は降ってこないので手でビルドする必要があります。しかし、ISSUEなどをみているかぎりビルドは超大変っぽいので手を出す気がおきません。

ということで、Firefox+seleniumPythonでやってみます。

オチ

すっごい遅いから、やめた方が良い。

セットアップ

$ sudo apt install firefox-esr xvfb -y
# geckodriverを入手します。本家のリリースは以下なのですが、arm7です、raspi zeroはarm6である必要があります。
# https://github.com/mozilla/geckodriver/releases

# かといって、rustでビルドするのはしんどい、ので、無保証のblobを今回つかってみました。
# 正直良い行動とはいえませんので、みなさんはビルドしましょう。

# https://github.com/d0ku/GeckoDriver_ARMv6/tree/0.18.0
$ wget https://github.com/d0ku/GeckoDriver_ARMv6/raw/0.18.0/geckodriver
$ chmod +x geckodriver
$ mv geckodriver /usr/local/bin
# いるのかわかりません
$ xvfb-run firefox -CreateProfile default
# Pythonでやりたいので、ライブラリをいれます
$ sudo python -m pip install selenium
$ sudo python -m pip install pyvirtualdisplay

以下のようなコードを書き、実行します。

from selenium import webdriver
from pyvirtualdisplay import Display

display = Display(visible=0, size=(800, 600))
display.start()

driver = webdriver.Firefox()
driver.get('http://s.cfe.jp')
driver.save_screenshot('screenshot.png')
driver.quit()

大体1〜2分くらいかかってスクショができます。おつかれさまでした

なお、本ブログサイトは10分くらいねばった上で、メモリ不足でおちました。 マイコンから見れば無尽蔵の性能をもつraspberry pi zero w とはいえ、こういう処理荷が重かった模様。

トラブルシュート

geckodriver.logをみましょう。

大抵は仮想ディスプレイ(xvfbとか)がうまくいってないんじゃないですかね。

firefoxが終了しない

ISSUEにもあるのですが、なにかしらダイアログをだして固まるようです。荒々しく皆殺しです。

$ killall geckodriver
$ killall firefox-esr
$ killall Xvfb

まとめ

上にもかきましたが、Web1.0的なしょぼいサイト以外ではなかなかきびしい。むりやりswap領域をふやしたり、Headless Firefoxを使い回せばいいのかもしれませんが、そうもいってられないこともある。

外部のスクリーンショット生成APIを使う方が良いですね。

さて、皆様の楽しいGWを祈っております。

セパレータがはいったWifi環境で、隣のPCにsshするメモ

八王子のいいかんじのコワーキングスペースであるところのfabbitにいって、いい感じだなとおもいました(小学生の日記)

fabbit八王子 | コワーキングスペースfabbit(ファビット)

なんかちょっとした渋谷のIT企業っぽいですよね、八王子とはおもえん。

デジタルファブ(3Dプリンタ、レーザーカッター)も気になるし、土曜にもかかわらず人もいたのでいきなり消滅しなさそうで*1それもよい。

ぜひ続いてほしい。


さて、ちゃんとしたコワーキングスペースなどが提供するWifiは、セパレータ(プライバシーセパレーター、ネットワーク分離、APアイソレーションWifiでもなくてもポートセパレータなど)で隣のマシンと通信はできない。

これは嬉しいことではあるのですが、隣のPC、たとえばヘッドレスなRaspberry pi と通信したい時には少々面倒。

Raspiなら一つ前でも言及したUSB Gadget Etherなどで接続するのが一番だとおもいますが、まあこいつがちゃんと動かない時もあるので私はシリアルでMacとRaspiをつないでしまう。

となるとシェルはいいけどscpがないのでファイルが転送できない *2 、かといって手持ちのスマホでAPをたててつなぐと作業してる内にギガが減る

…という非常に限られた状態においては、インターネットにおいてあるサーバーを経由してsshすることになりますよね。それのメモです。

接続先としたいPCで実行

(上にも書きましたが、なんらかの手法でシェルにはさわれないと駄目です)

$ ssh -R 1122:127.0.0.1:22 your_login_id@your_server.example.jp

screenとかで永続化しておくとよいでしょう。

操作元からの接続

$ ssh -o "ProxyCommand ssh -W %h:%p your_server.example.jp" -p 1122 pi@127.0.0.1

# scpはポート指定がpからPに変わるので注意…してても間違える
$ scp -o "ProxyCommand ssh -W %h:%p your_server.example.jp" -P 1122 pi@127.0.0.1:~/sample.png .

まあ、こういうOptionは.ssh/configに書くのが筋なんですが、まあ使い捨てだし。

sshだけでない場合はSocks

$ ssh -o "ProxyCommand ssh -W %h:%p your_server.example.jp" -p 1122 -D 1080 pi@127.0.0.1

# した上で、ブラウザのProxyでSOCK5 localhost:1080設定

以上です。

*1:昔、最寄りのコワーキングスペース消滅した

*2: cat > file?バイナリだときびしくない?ZMODEM?時代錯誤じゃない?っていうか115200bpsだよ!