そんな今日この頃でして、、、

コード書いたり映画みたり。努力は苦手だから「楽しいこと」を探していきたい。

CasperJSであしあとポイントをちょろまかす話のつづき

以前に上げた「CasperJSを使ってあしあとポイントをちょろまかす話」のエントリが結構安定してアクセスされてて、 我ながら驚いていたりする今日この頃。

blue1st.hateblo.jp

スクレイピングというジャンルが世間的にそんなに注目度が高いのか、 はたまた小銭チャリンチャリンなネタのウケが良いんだか…

そんなわけで今回は対象サイトに修正が入ったのでそれに対応したという話と、おまけでDocker化した話。

具体的に どうやって対応していくかという方法論 に焦点を絞って書いてみようと思う。


前回のあらすじ

愛用している某書店サイトが「あしあとポイント」というサービスをやっていて、 これは所定のページにある「あしあと」ボタンを一日一回押下すると、 翌月買い物で使用できるポイントがもらえるというものだった。

怠惰な僕はバッチ処理で自動で押させてみようと考えたのだが、 どうやらこのボタンはJavascriptの処理も織り交ぜており、 単純にhttpリクエストを飛ばすだけでは対応できなそうな感じ。

そこで、CasperJSを用いてこれに対応してみた、というお話。


「あしあと」の仕様変更

さて今回の話の発端。

いつものようにサイトを巡回していると、あしあとのページにスタンプがついていないことに気づいた。

よくよく説明書きを見てみると、どうやらサービスの仕様が変わったらしく、 前に作ったスクリプトでは不十分になったようだ。

f:id:blue1st:20160405110351p:plain

肝心のあしあとページについても自分で触って確認してみると、 前までが単にボタンを押下すればポイントがついたのに対し、 新しいものは

  1. あしあとボタンを押下
  2. くじ引きのダイアログが表示される
  3. 特定の座標を押下することで完了

という手順を踏む必要がありそうだ。

f:id:blue1st:20160405105945p:plain

f:id:blue1st:20160405110520p:plain


要素を調べる

何はともあれ、各要素を調べてみる必要がある。

おなじみChromeディベロッパーツールを使い、 要素のパスや記述を確認していく。

あしあとボタン

まずは「あしあと抽選にチャレンジ」ボタン。

ディベロッパーツールから該当の要素のパスを抽出してみる。

f:id:blue1st:20160405110328p:plain

どうやら#pbBlock2525988 > div.stBoxBorder04 > p > a > imgらしい。

また、ボタンそのものがどういった動きをするのかを調べるために、 ボタン画像を囲んでいるaタグを読んでみると、

<a href="#logBox" rel="litebox" showclosebutton="true">

といった風に独自要素っぽい記述もあって、押下きっかけでJavascriptが動いてそうな感じだ。

(まあダイアログ開く動作的に当たり前ではあるけれども)

従って、 #pbBlock2525988 > div.stBoxBorder04 > p > a > imgをクリックする が必要な動作の一つ目になる。

抽選ダイアログ

次に抽選ダイアログ。

表示されている本の中から三択でどれか一冊をクリックするわけだが、 これはどうやら画像の上にmapタグとareaタグで示されているもよう。

f:id:blue1st:20160405110300p:plain

そして、座標として示されたareaタグが押下されると、 href要素に記述されたJavascriptsetFootMarkLot(1~3)が実行される。

こっちもパスを調べてみると#imgfootMarkLot > area:nth-child(1~3)のようだ。

ソシャゲ的な発想からいえば、1~3のどれを選んだところで抽選はサーバ側で行われるのだろう。

従って、 #imgfootMarkLot > area:nth-child(1)のhref要素を実行する が必要な動作の二つ目になる。


対応したスクリプトに書き換える

必要な動作が分かったので、これをスクリプトに実装していく。

URLは前回と変わらないので、 ページを開いた後の処理を書き換えていけば良い。

前回同様にページのJavascriptが動いている状態を再現する必要があるので、 evalute内に記述していくと、以下のようなスクリプトになる。

あしあとちょろまかし

抽選の方のarea要素をクリックでも良さそうだが、 何度かやってみた感じ上手く行かなかったので、 安直に前回も使ったhref要素の中身を取り出して実行する形に。

Docker化する

以前のOS載せ替えの記事でもちょっと述べてはいるが、 サーバにはミドルウェアやツールをごちゃとちゃとインストールせずに、 Dockerで解決できそうなものは極力そっちを使う方針。

blue1st.hateblo.jp

で、CasperJSにも良い感じのイメージvidiben/casperjsがあり、 調べてみるとコンテナのホームディレクトリにscript.jsという名称で実行したいスクリプトをマウントしてやれば、 コンテナを起動すると実行してくれそう。

というわけで、今回作成したスクリプトをscript.jsとリネームし、 以下のコマンドをcronで定期的に叩くように設定して完了。

docker run --rm -v <スクリプトの置いてあるディレクトリ>:/home/casperjs vidiben/casperjs


追記:ちゃんとスクレイピング用途で使うなら…↓

blue1st-tech.hateblo.jp



設置して三日ほどしたが、ブラウザから確認すると無事動作していそうで一安心。

f:id:blue1st:20160405110622p:plain


それにしても、この抽選はどんな期待値なんだろ?

ボタン押下と同時にアタリとかハズレとか出てくるんで普通に考えると純粋な確率による抽選だと思うんだが、 本数が明示されてるのはちょっと「?」な感じだ。

【今月の当選ポイント】
・1等100ポイント:100本(1日あたり)
・2等1ポイント:49,900本(1日あたり)

本当に当たりに限りがあるのなら早めに押した方得なのかなとは思うが、 そんな作りにしてるとは考えづらい。

期待値設定はストレートに考えると前回の「一ヶ月間皆勤で100pt+毎日の加算で30pt前後」と同等もしくはそれより若干低いくらいに設定してくると思うんだけど、 まあこれはしばらく運用を続けてみてのお楽しみといったところか。


JS+Node.jsによるWebクローラー/ネットエージェント開発テクニック

JS+Node.jsによるWebクローラー/ネットエージェント開発テクニック

↑今回使ったCasperJSも載ってそう。内容的には一番親和性高いっぽい。

↓その他各種言語のものが出版されてる。

Rubyによるクローラー開発技法 巡回・解析機能の実装と21の運用例

Rubyによるクローラー開発技法 巡回・解析機能の実装と21の運用例

PythonによるWebスクレイピング

PythonによるWebスクレイピング

実践 Webスクレイピング&クローリング-オープンデータ時代の収集・整形テクニック

実践 Webスクレイピング&クローリング-オープンデータ時代の収集・整形テクニック