Hpricot からテキストを取り出す
scrAPIよりも使いやすい感じのHpricotですが、「innerText」が上手くHTMLエンティティーを戻してくれないので、違うメソッドをつけてみました。
require "rubygems" require 'hpricot' class Hpricot::Elem def [](a) CGI.unescapeHTML(get_attribute(a)) end def to_text r = [] traverse_text{|text| case text when Hpricot::CData r << text.content else r << CGI.unescapeHTML(text.inner_text.gsub("\n"," ").gsub(/ +/," ").strip) end } r.join end end
hp = Hpricot('<html><boge href="hoge&neko">test& test & test<![CDATA[ hoge <&> hoge ]]></boge>') hp.root.inner_text #オリジナル # => "test& test & test hoge <&> hoge " hp.root.to_text # => "test& test & test hoge <&> hoge " hp.root.at("boge").get_attribute(:href) #オリジナル # => "hoge&neko" hp.root.at("boge")[:href] # => "hoge&neko"
Hpricotはcssセレクタもつかえるよ!
知らない人も多いようだけど
doc = Hpricot(open("http://d.hatena.ne.jp/keyword/%BA%B0%CC%EE%A4%A2%A4%B5%C8%FE")) doc.at("span.furigana").to_text # => こんのあさみ doc.at("span.title > a:first-child").to_text # => 紺野あさ美 doc.at("ul.list-circle > li:first-child > a").to_text # => アイドル
(サンプルは 川o・-・)<2nd life - ruby のスクレイピングツールキット scrAPI をインスパイア)
t*追記:
CGI.unescapeHTML が、そのままだと 「& &」とか上手く元に戻せないので、http://d.hatena.ne.jp/walf443/20070204/1170605669 の修正をするといいよ!