今までWebスクレイピングする時には、Go言語 + agouti + selenium + chrome driver + chromeの組み合わせでプログラムしていた。 しかし、この場合はchromeとchrome driverのバージョンを揃えないと動かない。 chromeは自動でバージョンアップしてしまうため、chrome driverとバージョンを揃えるのが面倒になっていた。
そこで、これからはGo言語 x chromedp x chromiumでWebスクレイピングしていく。
chromium
AWS Lambdaは容量制限があるため、直接chromiumを格納することはできない。 そのため、AWS Lambda Layerにchromiumを格納し、WebスクレイピングするGoプログラムをAWS Lambdaに格納する。
- chromium : AWS Lambda Layer
- Goプログラム : AWS Lambda
さて、ここでAWS Lambda Layerに格納できるchromiumを用意する。 いくつかchromium起動まで失敗してきたので、その変遷を記載しておく。
- GitHub > adieuadieu内のバイナリを使用: chromiumのバージョンが60.0.3095.0のため古くてchromedpと通信できない
- GitHub > adieuadieuを手動ビルド: MAC失敗。自宅のLinuxは古くて失敗。
- GitHub > shelfio内のバイナリを使用: python用のもので、通常のchromiumが格納されてなかったため失敗。
- GitHub > pahudで取得: 成功。バージョンは86.0.4240.111。
1
|
|
の結果のlayer.zipを使用する。 pahud/lambda-layer-headless-chromiumのbuild.shを確認したところ、結局adieuadieuのdockerからコピーしていることがわかる。
1 2 3 4 |
|
AWS Lambda Layer
layer.zipをAWS Lambda Layerに登録する。 なお、layer.zipが50MBを超えているため、zipファイルを直接登録することはできない。 必ず、AWS S3経由で登録すること。
layer.zipを解凍すると以下のディレクトリ構成となっている。
1 2 3 4 5 6 |
|
に書かれている通り、Lambda Layerは /opt に展開される。 しかし、 /opt はPATHに入っていないため、実行ファイルを展開しても検索することはできない。 /opt/bin はPATHに入っているため、予めzipファイル生成時にbinディレクトリ内に実行ファイルを格納すれば良い。 しかし、今回使用するlayer.zipはPATHが通っていないディレクトリにheadless-chromiumがあるため、 Go言語側でheadless-chromiumのパスを指定する。
登録時に以下の設定も行う
- 「互換性のあるランタイム」 に Go1.xを追加
AWS Lambda
- AWS Lambda Layerの登録
- 「設定 > 一般設定 > メモリ」 を 512MBに変更
- 「設定 > 一般設定 > タイムアウト」 を 1分に変更
AWS Lambda Layer上のchromiumを起動するため、 chromedpのExecAllocatorOptionは以下を設定した。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
その他問題
施策
実際動かすことができるようになるまでに2週間ほどかかった。 chromiumバイナリの取得・chromiumの起動オプションの設定にほとんどの時間がかかっている。 問題解決するため、素早くテストするために良かった点をまとめておく。
- AWS Lambdaをコマンドラインからdeployした ビルド&デプロイ時間を大きく削減できた。多くのchromiumの起動オプションを試していたため有用だった。
1
|
|
- ローカル環境&AWS Lambda環境の双方をビルドできるようにGo言語のbuild tagを活用 ほぼ同じコードでローカル環境とAWS Lambda環境を比較することで問題の切り分けに貢献した
- chromiumのログを出力するようにGoプログラムを変更 chromiumがエラーで起動しない時など、chromium側のログがないと問題を切り分けることはできなかった
1 2 3 4 5 6 7 |
|
その他問題:No usable sandbox
AWS Lambdaのログ
1 2 |
|
Qiita > CircleCI で puppeteer のテストを実行する を見ると、chromium起動時に以下の引数を足す必要があるとのこと。
1
|
|
Go言語のコードに落とすと以下となる。
1 2 3 4 5 6 |
|
その他問題:websocket url timeout reached
AWS Lambdaのログ
1 2 3 4 |
|
恐らく、DevTool protocolのソケットを開けなかったと思われる。