今日はスクレイピングの話をします。
今回のターゲットは三菱東京UFJダイレクト。金融機関もウェブサービスを提供するようになり、金にまつわる情報を電子化しやすくなりましたが、かれらが API を提供しているわけではないので、私たちのほうで取得・加工をしてやる必要があります。今やウェブサイトであれば当然のように JavaScript を使っているわけなので、いわゆる mechanize、つまり HTML の解釈をおこない、リンクのクリックやフォームの送信をシンプルに実装するようなやり方でのスクレイピングはすでに無理筋だといえます。
もちろん今日においてはブラウザオートメーションという方法がすでにありますので、これを利用してやれば、なんの憂いもなく実際に人間が使うようなブラウザをプログラマティックに操作することができます。現在は Selenium WebDriver がデファクトで、これが使用する JSON Wire Protocol というプロトコルを通じて様々なブラウザを操作できます。
JSON Wire Protocol の実装はいろいろな言語にありますが、今回は言語に JavaScript を利用することにして、クライアント側のライブラリとして Protractor と WebdriverIO をそれぞれ使ってみます。個人的に、過去には 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 の上に実装されている。
- なので WebDriverJS の API も使うことになるんだけど、公式にはドキュメントがあまりなされていない……
- http://appfigures.github.io/webdriver-js-api-reference/ が便利かも。
- Protractor の API は http://angular.github.io/protractor/#/api
- JS テストフレームワーク(Jasmine/Mocha/Cucumber.js)と組み合わせることを前提としている。
- WebDriverJS がそうだからなのだけど Promise をいい感じの順番で実行してくれるので、メソッドチェインを長々とつなげなくてもすむ。
- こんな感じ。内部は Promise なのだけど、書いた順番に解決してくれる(Promise が解決すると次に進む)。
- http://angular.github.io/protractor/#/control-flow
- Selenium 側の実装のインストールや起動まで自動でおこなってくれて便利。
- bin/webdriver-manager というのがいい感じにやってくれる。
protractor
経由で起動するとテストファイルの内部でbrowser
というグローバル変数が定義され、これを通じて Protractor(や WebDriverJS)の API を使用できる。
Protractor で AngularJS を使っていないサイトを対象にする
Protractor は AngularJS 用のライブラリなので、普通に使おうとすると AngularJS の読み込みを待ってから操作をはじめようとしてしまう。これを回避するには以下のようにしてやればいい。ただしいい感じに条件が整うまで実行を遅らせてくれるみたいな機能が使えなくなるので注意。
browser.ignoreSynchronization = true;
セキュリティに気をつける
普通に ChromeDriver 経由で Chrome を起動すると、
サポートされていないコマンドラインフラグ --ignore-certificate-errors を使用しています。これにより、安全性とセキュリティが損なわれます。
というバーが表示される。銀行のサイトにアクセスするのにセキュリティを損なっては意味が無いので、protoractor.conf.js で Chrome に与えるオプションを制御して、当該のフラグを落とすということをしています。
WebdriverIO
サンプル
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 など複数のスタイルで操作を組み立てることができる。
この手の話をまとめだすと本一冊ぶんになっちゃうな〜と思ってたら、つい最近こんな本が出てました。具体的なテクを知るにはちょうどよさそうですね!
- 作者: Satya Avasarala,Sky株式会社玉川竜司
- 出版社/メーカー: オライリージャパン
- 発売日: 2014/09/18
- メディア: 大型本
- この商品を含むブログ (1件) を見る
追記
以下の本にも紹介があるそうです。
Rubyによるクローラー開発技法 巡回・解析機能の実装と21の運用例
- 作者: るびきち,佐々木拓郎
- 出版社/メーカー: SBクリエイティブ
- 発売日: 2014/08/25
- メディア: 大型本
- この商品を含むブログ (2件) を見る