JavaScript
Node.js
GitHub
PhantomJS
casperJs

PhantomJS と CasperJS でスクレイピングして json で保存し GitHub で公開した

More than 3 years have passed since last update.


概要 と 動機

5374 Official Website のデータを使ったサービスを作ることになった。

本来はゴミの日を提供するREST APIなどがあればいいのだが、現実にはゴミの日を提示するビューがあるだけ & ゴミの日パターンをJavaScriptでがんばって人間にやさしくしている。

「がんばって JavaScript(jQuery) がゴミの日を計算 & DOMを操作してビューを作ってくれる、その結果が欲しい」という状況であり、このデータを毎朝取得、そのデータをjson化し、GitHubに設置して、みんなに使ってもらおうというもの。

調べた結果、以下のものを使い、PhantomJSでヘッドレスで操作後のDOMを取得することにした。定期実行はjenkins + Docker でやる。

PhantomJS | PhantomJS

CasperJS, a navigation scripting and testing utility for PhantomJS and SlimerJS


成果物

PharaohKJ/scrape_5374

PhalanXware/scraped-5374


やったこと と ハマりどころ


  1. 動作環境の準備

  2. コードを書く

  3. Publish用のアカウントをGitHubに作る

  4. Jenkinsに仕込む


1. 動作環境の準備

OSXで PhantomJS と CasperJS を用意したりしたが、全然うまく動かないでドハマリ。

そもそもCasperJSのメンテがアレなのかな?とりあえずそこら中を見まわった結果、動く組み合わせのソースコードHashを推測し用いるようにした。

そもそも最終的にはDocker運用しようと思っているので、Dockerを使う。PhantomJSのLinuxインストールは自前ビルドが推奨らしく、OSXのDocker上でbuildしたら1時間ぐらいかかった!ので、以下の成果物を使って欲しい・・・。

scrape_5374/Dockerfile at master · PharaohKJ/scrape_5374

Docker Hub


2. コードを書く

Node.js/JavaScriptを書き慣れてないのがバレバレな感じでだいぶ苦戦した。特に変数スコープ、シーケンス周り。


casper.evaluate がピンとこない

公式ドキュメントをちゃんと読め。まぁつまり、PhantomJSのページ内でevalということである。


デバッグログがでない

CasperJSのヘッドレスブラウザ内のconsole.logの出力をコンソールに出す - 日々精進


値を渡したり受け取ったりできない

下記コードな感じ、toValueを指定すると、evalの先の関数に引数としてわたされる。この先の関数のreturn値ret_valueがgotValueとなる。


capture.js

      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() で登録した順に実行する、ということに気づいたらできた。つまり


  1. 地域一覧取得

  2. 地域一覧分 casper.then をする


    1. 地域指定

    2. 少しまってデータ取得 & キャプチャ



  3. 取得したデータを書く

とやるべきで、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:tok_token_@github.com/yourname/awesome-app.git とかにするとよい。


課題

スクショ、ドロップダウンボックスで地域を指定しているつもりが、ぜったいに末尾になってる・・・。