ruby のスクレイピングツールキット scrAPI
http://blog.labnotes.org/category/scrapi/
ruby でスクレイピングして web の情報を取得するのには、今まで正規表現か xpath でやってたので、わりと面倒でした。で、ふと scrAPI というスクレイピングツールキットを知ったのですが、これがかなり便利そう。
このツールキットを使うと、CSS3 なセレクタを記述することで、要素を取得することができます。たとえばとあるサイトのリンクを全部取得したければ、
require 'rubygems'
require 'scrapi'
require 'open-uri'
require 'nkf'
require 'pp'
$KCODE = 'u'
links = Scraper.define do
process "a[href]", "urls[]"=>"@href"
result :urls
end.scrape(URI.parse('http://www.hatena.ne.jp/')).sort.uniq
pp linksな感じですっきり記述することができます。
たとえばはてなダイアリーキーワードページから、タイトル、ふりがな、URL、カテゴリを取得したければこんな感じなコードで。
keyword_scrapper = Scraper.define do
process 'span.title > a:first-child', :title => :text, :url => '@href'
process 'span.furigana', :furigana => :text
process 'ul.list-circle > li:first-child > a', :category => :text
result :title, :furigana, :url, :category
end
html = NKF::nkf('-w -m0', open('http://d.hatena.ne.jp/keyword/%BA%B0%CC%EE%A4%A2%A4%B5%C8%FE').read)
pp keyword_scrapper.scrape(html, :parser => :html_parser)結果は構造体として取得できるのでアクセスも楽々です。
#<struct title="紺野あさ美", furigana="こんのあさみ", url="/keyword/%ba%b0%cc%ee%a4%a2%a4%b5%c8%fe?kid=800", category="アイドル">
一つはまったのが、デフォルトの html の構文解析では Tidy のライブラリを使うのですが、このライブラリがマルチバイト文字列をエンティティにしちゃうので困るという罠が…。そのため、scrape のオプションで pure ruby の HTMLParser を指定することで回避できます。