ちょっと前に試そうと思って、そのまま放置していたruby製のクローラー「Masque」を試してみました。ruby製のクローラーは、他にはAnemoneという優秀なものがあります。その上で何故というと、Anemoneにはない特性があるからです。
MasqueはCapybaraのDSLで記述出来るWebクローラーです。つまりCapybaraを動かす為のものなので、JavaScriptも解釈が出来るということです。また場合によっては、レスポンシブルデザインのサイトの確認も出来ます。一方で、Anemoneはあくまで個別個別のHTMLを取得する為のクローラーなので、JavaScriptを多用しているサイトでの情報取得に向きません。どちらが優れているという訳ではないので、用途に応じて使いこなせばよいでしょう。
Masqueのインストール
$ gem install masque
Fetching: headless-1.0.1.gem (100%)
Successfully installed headless-1.0.1
Fetching: mini_portile-0.5.2.gem (100%)
Successfully installed mini_portile-0.5.2
Fetching: nokogiri-1.6.1.gem (100%)
Building native extensions. This could take a while...
Successfully installed nokogiri-1.6.1
Fetching: mime-types-2.0.gem (100%)
Successfully installed mime-types-2.0
Fetching: rack-1.5.2.gem (100%)
Successfully installed rack-1.5.2
Fetching: rack-test-0.6.2.gem (100%)
Successfully installed rack-test-0.6.2
Fetching: xpath-2.0.0.gem (100%)
Successfully installed xpath-2.0.0
Fetching: capybara-2.1.0.gem (100%)
IMPORTANT! Some of the defaults have changed in Capybara 2.1. If you're experiencing failures,
please revert to the old behaviour by setting:
Capybara.configure do |config|
config.match = :one
config.exact_options = true
config.ignore_hidden_elements = true
config.visible_text_only = true
end
If you're migrating from Capybara 1.x, try:
Capybara.configure do |config|
config.match = :prefer_exact
config.ignore_hidden_elements = false
end
Details here: http://www.elabs.se/blog/60-introducing-capybara-2-1
Successfully installed capybara-2.1.0
Fetching: capybara-webkit-1.0.0.gem (100%)
Building native extensions. This could take a while...
ERROR: Error installing masque:
ERROR: Failed to build gem native extension.
/Users/username/.rvm/rubies/ruby-2.0.0-p247/bin/ruby extconf.rb
Command 'qmake -spec macx-g++' not available
Gem files will remain installed in /Users/username/.rvm/gems/ruby-2.0.0-p247@masque/gems/capybara-webkit-1.0.0 for inspection.
Results logged to /Users/username/.rvm/gems/ruby-2.0.0-p247@masque/gems/capybara-webkit-1.0.0/./gem_make.out
qmakeがないとエラーが出ます。インストール方法を探してみると、Homebrewでインストール出来るようです。パッケージ名は、qmakeではなくqtです。
$ brew install qt
Warning: Building source; cellar of qt's bottle is /usr/local/Cellar
==> Downloading http://download.qt-project.org/official_releases/qt/4.8/4.8.5/qt
######################################################################## 100.0%
==> ./configure -prefix /Users/username/tools/homebrew/Cellar/qt/4.8.5 -system-zli
==> make
==> make install
==> Caveats
We agreed to the Qt opensource license for you.
If this is unacceptable you should uninstall.
==> Summary
🍺 /Users/username/tools/homebrew/Cellar/qt/4.8.5: 2778 files, 119M, built in 23.6 minutes
コマンド一発でインストール出来るのですが、割と時間が掛かります。
気を取り直して、再度gemでmasqueのインストール
$ gem install masque
Building native extensions. This could take a while...
Successfully installed capybara-webkit-1.0.0
Fetching: http_parser.rb-0.5.3.gem (100%)
Building native extensions. This could take a while...
Successfully installed http_parser.rb-0.5.3
Fetching: eventmachine-1.0.3.gem (100%)
Building native extensions. This could take a while...
Successfully installed eventmachine-1.0.3
Fetching: faye-websocket-0.4.7.gem (100%)
Building native extensions. This could take a while...
Successfully installed faye-websocket-0.4.7
Fetching: poltergeist-1.3.0.gem (100%)
Successfully installed poltergeist-1.3.0
Fetching: masque-0.3.1.gem (100%)
Successfully installed masque-0.3.1
Parsing documentation for capybara-webkit-1.0.0
Installing ri documentation for capybara-webkit-1.0.0
Parsing documentation for eventmachine-1.0.3
unable to convert "\xCF" from ASCII-8BIT to UTF-8 for lib/fastfilereaderext.bundle, skipping
unable to convert "\xCF" from ASCII-8BIT to UTF-8 for lib/rubyeventmachine.bundle, skipping
Installing ri documentation for eventmachine-1.0.3
Parsing documentation for faye-websocket-0.4.7
unable to convert "\xCF" from ASCII-8BIT to UTF-8 for lib/faye_websocket_mask.bundle, skipping
Installing ri documentation for faye-websocket-0.4.7
Parsing documentation for http_parser.rb-0.5.3
unable to convert "\xCF" from ASCII-8BIT to UTF-8 for lib/ruby_http_parser.bundle, skipping
Installing ri documentation for http_parser.rb-0.5.3
Parsing documentation for masque-0.3.1
Installing ri documentation for masque-0.3.1
Parsing documentation for poltergeist-1.3.0
Installing ri documentation for poltergeist-1.3.0
6 gems installed
今回はすんなりインストール出来ます。早速サンプルソースを走らせてみましょう。サンプルソースは以下の通りです。
require "masque"
m = Masque.new(:display => 99, :driver => :webkit) # or :driver => :poltergeist
m.run do
# Capybara::DSL syntax
# https://github.com/jnicklas/capybara#the-dsl
visit "http://www.google.com/"
fill_in("q", :with => "capybara")
find('*[name="btnG"]').click
titles = evaluate_script <<-JS
(function(){
var titles = Array.prototype.map.call(
document.querySelectorAll('h3 a'),
function(a) {
return a.innerText;
}
);
return titles;
})();
JS
puts titles.join("\n")
end
サンプルソースを実行してみると、下記のようなエラーが出ました。Xvfbがないとのことです。Xvfbは仮想フレームバッファで、Xを起動していないマシンでもXの仮想的なXフレームバッファを使えるようにする為のものです。これを入れておけば、Xのライブラリが使えるようになります。
$ ruby masque_sample.rb
/Users/username/.rvm/gems/ruby-2.0.0-p247@masque/gems/headless-1.0.1/lib/headless/cli_util.rb:9:in `ensure_application_exists!': Xvfb not found on your system (Headless::Exception)
from /Users/username/.rvm/gems/ruby-2.0.0-p247@masque/gems/headless-1.0.1/lib/headless.rb:68:in `initialize'
from /Users/username/.rvm/gems/ruby-2.0.0-p247@masque/gems/masque-0.3.1/lib/masque.rb:50:in `new'
from /Users/username/.rvm/gems/ruby-2.0.0-p247@masque/gems/masque-0.3.1/lib/masque.rb:50:in `initialize'
from masque_sample.rb:2:in `new'
from masque_sample.rb:2:in `<main>'
さてどうしたものかと考えたのですが、基本的にはXがあれば良いはずです。MacでXはどうなっているかというと、入っていないのでXQuartzを使えと公式ページに書いています。XQuartzはdmg形式で配布されてるので、ダウンロードしてインストールしましょう。インストール後に再起動して環境を反映さえます。
再度、実行してみます。何やら結果が出ていますね。これは、masqueがGoogleでcapybaraを指定して検索ボタンを押して、その結果を取得しているのです。
$ ruby masque_sample.rb
jnicklas/capybara · GitHub
capybara の画像検索結果
Capybara - Wikipedia, the free encyclopedia
フレームワークで実践! JavaScriptテスト入門(5):Capybara ...
capybara で快適なテスト生活を - SlideShare
Capybara Games
Capybara - GitHub Pages
Capybara の README 意訳 - おもしろWEBサービス開発日記
Capybara Madness
RSpecとCapybaraでJavaScript/Ajaxをテストする - Rails 雑感 - Ruby ...
capybara | RubyGems.org | your community gem host
Masqueの構造
最初に書いた通り、MasqueはCapybaraのDSLを記述出来るクローラーです。それを念頭にソースを見ると、以下のソースの意味が直ぐ解ります。
visit "http://www.google.com/"
fill_in("q", :with => "capybara")
find('*[name="btnG"]').click
とここまで書いて、Capybaraとの違いが気になってきます。同じ処理をCapybaraで書くと、下記のようなソースになります。
require 'capybara'
require 'capybara-webkit'
include Capybara::DSL
Capybara.default_driver = :webkit
visit "http://www.google.com/"
fill_in("q", :with => "capybara")
find('*[name="btnG"]').click
titles = evaluate_script <<-JS
(function(){
var titles = Array.prototype.map.call(
document.querySelectorAll('h3 a'),
function(a) {
return a.innerText;
}
);
return titles;
})();
JS
puts titles.join("\n")
DSLの宣言など、一部の違いがあるだけです。結論としては、MasqueはCapybaraのラッパーとして一部の値を上書きして使いやすくしているだけです。CapybaraのDSLを使いますよという時点で、そりゃそうだという結論です。