詩と創作・思索のひろば

ドキドキギュンギュンダイアリーです!!!

Fork me on GitHub

まだmechanizeで消耗してるの? WebDriverで銀行をスクレイピング(ProtractorとWebdriverIOを例に)

今日はスクレイピングの話をします。

今回のターゲットは三菱東京UFJダイレクト。金融機関もウェブサービスを提供するようになり、金にまつわる情報を電子化しやすくなりましたが、かれらが API を提供しているわけではないので、私たちのほうで取得・加工をしてやる必要があります。今やウェブサイトであれば当然のように JavaScript を使っているわけなので、いわゆる mechanize、つまり HTML の解釈をおこない、リンクのクリックやフォームの送信をシンプルに実装するようなやり方でのスクレイピングはすでに無理筋だといえます。

f:id:motemen:20140930200107p:plain

もちろん今日においてはブラウザオートメーションという方法がすでにありますので、これを利用してやれば、なんの憂いもなく実際に人間が使うようなブラウザをプログラマティックに操作することができます。現在は Selenium WebDriver がデファクトで、これが使用する JSON Wire Protocol というプロトコルを通じて様々なブラウザを操作できます。

JSON Wire Protocol の実装はいろいろな言語にありますが、今回は言語に JavaScript を利用することにして、クライアント側のライブラリとして ProtractorWebdriverIO をそれぞれ使ってみます。個人的に、過去には CasperJS というライブラリを利用してスクレイピングをしていました。これは PhantomJS という GUI なしの WebKit によるブラウザ実装を操作するライブラリですが、上に挙げたような方法で PhantomJS に限らないブラウザを操作できる(PhantomJS 自身も Ghost Driver という名前で WebDriver に対応しています)現在、PhantomJS(と SlimerJS)しか使えない CasperJS を選ぶ理由はなさそうです。

さて、Protractor と WebdriverIO それぞれについて見ていきます。

Protractor

http://angular.github.io/protractor/

サンプル

example-scrape-websites/protractor at master · motemen/example-scrape-websites · GitHub

git clone してこのディレクトリで以下のコマンドを実行すると、Chrome が自動的に起動して三菱東京UFJダイレクトにログインし、残高を表示した上で先月の残高を YYYY-mm.tsv ファイルに書き出してくれます。

環境変数 MUFG_ID, MUFG_PASSWORD にそれぞれ必要な値を与えておいてください。

npm install
npm run scrape-mufg

特徴・長所

  • もともと AngularJS 用の E2E テストライブラリ。
  • Selenium オフィシャルのライブラリ WebDriverJS の上に実装されている。
  • JS テストフレームワーク(Jasmine/Mocha/Cucumber.js)と組み合わせることを前提としている。
  • WebDriverJS がそうだからなのだけど Promise をいい感じの順番で実行してくれるので、メソッドチェインを長々とつなげなくてもすむ。
  • Selenium 側の実装のインストールや起動まで自動でおこなってくれて便利。
    • bin/webdriver-manager というのがいい感じにやってくれる。
  • protractor 経由で起動するとテストファイルの内部で browser というグローバル変数が定義され、これを通じて Protractor(や WebDriverJS)の API を使用できる。

Protractor で AngularJS を使っていないサイトを対象にする

Protractor は AngularJS 用のライブラリなので、普通に使おうとすると AngularJS の読み込みを待ってから操作をはじめようとしてしまう。これを回避するには以下のようにしてやればいい。ただしいい感じに条件が整うまで実行を遅らせてくれるみたいな機能が使えなくなるので注意。

browser.ignoreSynchronization = true;

セキュリティに気をつける

普通に ChromeDriver 経由で Chrome を起動すると、

f:id:motemen:20140930195220p:plain

サポートされていないコマンドラインフラグ --ignore-certificate-errors を使用しています。これにより、安全性とセキュリティが損なわれます。

というバーが表示される。銀行のサイトにアクセスするのにセキュリティを損なっては意味が無いので、protoractor.conf.js で Chrome に与えるオプションを制御して、当該のフラグを落とすということをしています。

WebdriverIO

http://webdriver.io/

サンプル

example-scrape-websites/webdriverio at master · motemen/example-scrape-websites · GitHub

動かし方は Protractor の場合と同様です。ただしブラウザは Firefox が起動すると思う。

ちなみにこっちの方はお知らせを自動で読む機能はないです。お知らせが出る状態を意図的に作り出せないので……(だれか口座くれたら確認します)

特徴・長所

  • JSON Wire Protocol を叩くための JS のライブラリといったところ。
  • メソッドチェインとコールバックで操作を記述する。
  • テストに関する機能はないので、自分で好きなものを使える。
  • メソッドごとにソースコードのファイルが分かれていて、読みやすい(大事だと思う)。
  • Selenium の起動なども自分でやる必要がある。

総括

Protractor 便利だな〜と思ってたけど機能もりもりすぎてかえってつらい。どちらにしろ JS で書くと Promise/コールバック地獄になるのは間違いないので、ちょっと面倒なところは面倒。スクレイピングを日常使いするなら、Selenium に与える設定でブラウザを PhantomJS に置き換えるよう指定すれば headless に実行できるので便利です。

JavaScript (node)から WebDriver を扱うものには他にもこんなライブラリがあるそうです:

  • Nightwatch.js
    • テストフレームワークも兼ねているもよう。
    • コールバックをつなげていくスタイル。
  • WD.js
    • インタラクティブシェルが付属してて便利そうだった。
    • コールバックや Promise など複数のスタイルで操作を組み立てることができる。

この手の話をまとめだすと本一冊ぶんになっちゃうな〜と思ってたら、つい最近こんな本が出てました。具体的なテクを知るにはちょうどよさそうですね!

実践 Selenium WebDriver

実践 Selenium WebDriver

追記

Selenium Webdriverでのスクレイピングについて。利用するモジュールの話が色々あって、とても参考になる。/こちらも宜しくw Selenium Webdriverの例も載せてる。 http://www.amazon.co.jp/dp/4797380357 - dkfj のコメント / はてなブックマーク

以下の本にも紹介があるそうです。

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

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

はてなで一緒に働きませんか?