CapybaraとPhantomJS、Nokogiriを利用してのクローラー・スクレイピングの紹介です。
PhantomJSとは?
PhantomJSは、ヘッドレスブラウザと呼ばれるWebKitのエミュレータです。ヘッドレスブラウザとは、GUIではなくCUIから利用できるブラウザでプログラムから呼ばれます。UIのテストツールとしてSeleniumのようなサービスがあります。Seleniumはブラウザを直接操作するので、環境依存や動作が重いといった幾つかの問題点があります。そこでよく利用されるのがPhantomJSです。Seleniumに比べて、軽量というメリットがあります。RubyからPhantomJSを扱うライブラリとして、Poltergeistがあります。
Capybaraとは?
Capybaraは、WebシステムのUI層のテストをサポートするためのライブラリです。主にDSL機能とDriver機能があり、テストフレームワークやブラウザ&ブラウザシミュレータを透過的に扱うことができます。
Nokogiriとは?
Nokogiriは、Rubyで実装されたHTML/XMLの構文解析器(パーサー)です。Rubyの構文解析器としてはデファクト・スタンダードで、スクレイピングする際の必須のツールとなっています。Rubyで実装されたクローラー・スクレイピングライブラリの大部分は、内部的にNokogiriを利用しています。使い方の詳細は、下記のリンクを参照していただければと思います。
Ruby製の構文解析ツール、Nokogiriの使い方 with Xpath
PhantomJSとCapybaraのインストール
PhantomJSのインストールは、Windowsでは少し面倒くさいことが多いです。PhantomJSのサイトからダウンロードしてパスを通すことが必要です。Mac+HomeBrewであれば、下記のコマンドでインストールできると思います。
brew install phantomjs
その後に、PoltergeistやCapybaraをインストールします。
gem install nokogiri gem install poltergeist gem install capybara
Windowsのnokogiriのインストールはハマる確率が高いです。ビルド済みのgemをダウンロードする方をお勧めします。x86-mingw32(32ビット版)もしくは x64-mingw32(64ビット版)と書かれているものがWindowsようです。
※最近、64ビット版も提供されるようになったようですね。
スクレイピング
下記がCapybaraとPhantomjsとNokogiriを使ったサンプルスクリプトです。
require 'capybara' require 'capybara/dsl' require 'capybara/poltergeist' class Scrape #DSLのスコープを別けないと警告がでます include Capybara::DSL def initialize() Capybara.register_driver :poltergeist_debug do |app| Capybara::Poltergeist::Driver.new(app, :inspector => true) end Capybara.default_driver = :poltergeist Capybara.javascript_driver = :poltergeist end def visit_site page.driver.headers # => {} #ユーザエージェントの設定(必要に応じて) page.driver.headers = { "User-Agent" => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36" } #リファラーの偽装(特に不要) #page.driver.add_headers("Referer" => "http://yahoo.co.jp") page.driver.headers visit('http://www.yahoo.co.jp') #スクリーンショットで保存 page.save_screenshot('screenshot.png', :full => true) #within(:xpath, "//*[@id='toipcsfb']/div[1]/ul[1]") do #Nokogirオブジェクトの作成 doc = Nokogiri::HTML.parse(page.html) puts doc.title end end scrape = Scrape.new scrape.visit_site
ポイントとしては、次のとおりです。
・Capybara DSLのスコープを別ける
しないと、次のように警告でますよ
including Capybara::DSL in the global scope is not recommended!
・Nokogiriを使ってる
Capybaraの記法に慣れていない場合は、Nokogiriを作ってしまうのも1つの手です。
無駄が多いけど
このサンプルでは、面倒くさいのでJavaScriptによって動的に構築された部分とってませんが。。。
まとめ
JavaScriptバリバリのサイトからスクレイピングしたい場合、PhantomJSはお勧めです。少し重いものの、Seleniumでブラウザを動かすより断然軽量です。またブラウザのインストールが不要なので、サーバサイドで動かすことも容易です。今、PhantomJSをAWS Lambdaで動かそうかなと試しています。これが出来ればかなり面白いことが出来そうですね。
この辺りの話をまとめた、「Rubyによるクローラー開発技法」という本を出しています。ひたすらクローリングとスクレイピングしているので、何か参考になることがあればと思います。
See Also:
『Rubyによるクローラー開発技法』を書きました
RubyでWebスクレイピングの話をしてきました。第1回Webスクレイピング勉強会@東京
Ruby製の構文解析ツール、Nokogiriの使い方 with Xpath
あらためてRuby製のクローラー、"anemone"を調べてみた
オープンソースのRubyのWebクローラー"Anemone"を使ってみる