概要 と 動機
5374 Official Website のデータを使ったサービスを作ることになった。
本来はゴミの日を提供するREST APIなどがあればいいのだが、現実にはゴミの日を提示するビューがあるだけ & ゴミの日パターンをJavaScriptでがんばって人間にやさしくしている。
「がんばって JavaScript(jQuery) がゴミの日を計算 & DOMを操作してビューを作ってくれる、その結果が欲しい」という状況であり、このデータを毎朝取得、そのデータをjson化し、GitHubに設置して、みんなに使ってもらおうというもの。
調べた結果、以下のものを使い、PhantomJSでヘッドレスで操作後のDOMを取得することにした。定期実行はjenkins + Docker でやる。
CasperJS, a navigation scripting and testing utility for PhantomJS and SlimerJS
成果物
PharaohKJ/scrape_5374
PhalanXware/scraped-5374
やったこと と ハマりどころ
- 動作環境の準備
- コードを書く
- Publish用のアカウントをGitHubに作る
- Jenkinsに仕込む
1. 動作環境の準備
OSXで PhantomJS と CasperJS を用意したりしたが、全然うまく動かないでドハマリ。
そもそもCasperJSのメンテがアレなのかな?とりあえずそこら中を見まわった結果、動く組み合わせのソースコードHashを推測し用いるようにした。
そもそも最終的にはDocker運用しようと思っているので、Dockerを使う。PhantomJSのLinuxインストールは自前ビルドが推奨らしく、OSXのDocker上でbuildしたら1時間ぐらいかかった!ので、以下の成果物を使って欲しい・・・。
scrape_5374/Dockerfile at master · PharaohKJ/scrape_5374
2. コードを書く
Node.js/JavaScriptを書き慣れてないのがバレバレな感じでだいぶ苦戦した。特に変数スコープ、シーケンス周り。
casper.evaluate
がピンとこない
公式ドキュメントをちゃんと読め。まぁつまり、PhantomJSのページ内でevalということである。
デバッグログがでない
CasperJSのヘッドレスブラウザ内のconsole.logの出力をコンソールに出す - 日々精進
値を渡したり受け取ったりできない
下記コードな感じ、toValueを指定すると、evalの先の関数に引数としてわたされる。この先の関数のreturn値ret_valueがgotValueとなる。
gotValue = this.evaluate(function(to_value_param) {
// PhantomJS内でDOM操作
$('#select_area option').val(index).change();
return ret_value;
}, toValue);
動作が早過ぎるとスクショとかとれない
ウェイトいれないと、svgのレンダリング前にとれちゃったりしてた。
シーケンスがピンとこない
まず、地域一覧を取得して、その数だけループする。1回ごとにwaitを入れたい。ってことが全然できなかった。とりあえず casper.then
で実行するfunctionを順番に登録していき、最後の casper.run()
で登録した順に実行する、ということに気づいたらできた。つまり
- 地域一覧取得
- 地域一覧分 casper.then をする
- 地域指定
- 少しまってデータ取得 & キャプチャ
- 取得したデータを書く
とやるべきで、thenとrunとwaitの意味を把握していないと、全然思い通りのシーケンスにならないので注意。
3. Publish用のアカウントをGitHubに作る
k8s-bot (Kubernetes Bot)ちゃんをみて、弊社も作ろう!とし、 pxw-bot
ちゃんを用意したところ、「きみ、botだよね?ちゃんとサポートに連絡してね」ってなっちゃった!まーしょうがないよね。ただいまカスタマーサポートをお願いしているところ。
4. Jenkinsに仕込む
gitが鍵の指定に対応していないので ~/.ssh/config
に以下のように書く & デプロイキーを用意すること.
Host github-scraped-5374
User git
Port 22
HostName github.com
IdentityFile ~/.ssh/secret-key-for-deploy
TCPKeepAlive yes
IdentitiesOnly yes
うーん。正直鍵認証より、https + Token のほうがよさそう。つまるろころ、GitHubのアカウント設定を開き Presonal access tokens を選んで適なtokenを発行(repositoryアクセスのみとかがよかろう)し、git cloneするときとか .git/config の remote を https://account:token@github.com/yourname/awesome-app.git とかにするとよい。
課題
スクショ、ドロップダウンボックスで地域を指定しているつもりが、ぜったいに末尾になってる・・・。