LoginSignup
14

More than 5 years have passed since last update.

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

Last updated at Posted at 2015-12-26

概要 と 動機

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:token@github.com/yourname/awesome-app.git とかにするとよい。

課題

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

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14