BLOGTIMES
2010/01/30

HpricotのXPath実装はちゃんとしてない?

  ruby  scrape 
このエントリーをはてなブックマークに追加

HpricotのXPathの実装が完全でないことは薄々気づいていたものの、新たなライブラリを探すのも面倒だと思ってそのままにしていたのですが、とうとうちゃんと処理できない事例にあたってしまいました。

今回処理をしようとしたのは下記のコード中のようなHTMLから「<h2>aaa111</h2>の直後の<div class="a">の中身のテキストを取り出す」というもの。取り出したいdivにidなんかがついていればいいのですが、ちゃんと構造化されていないHTMLなのでどうしようもありません。

<html> <head><title>test</title></head> <body> <div class="b">001</div> <h2>aaa111</h2> <div class="a">002</div> <div class="b">003</div> <div class="b">004</div> <h2>aaa222</h2> <div class="a">005</div> <div class="b">006</div> <div class="b">007</div> </body> </html>

とりあえずノードを指定するXPathである //h2[text() = 'aaa111']/following-sibling::div[@class='b'][1]/text() はすぐに書けたのですが、Hpricotだと結果がきちんと帰ってきません。どうやらfollowing-siblingが使えないようです。ちなみに同じXPathをNokogiriに食わせるときちんと結果が帰ってくることが確認できたので、これを機にNokogiriに乗り換えてしまうことにしました。

検証したコードの例

#!/usr/bin/ruby require 'rubygems' require 'nokogiri' require 'hpricot' html = <<EOD <html> <head><title>test</title></head> <body> <div class="b">001</div> <h2>aaa111</h2> <div class="a">002</div> <div class="b">003</div> <div class="b">004</div> <h2>aaa222</h2> <div class="a">005</div> <div class="b">006</div> <div class="b">007</div> </body> </html> EOD noko = Nokogiri::HTML.parse(html) p noko.xpath("//h2[text() = 'aaa111']/following-sibling::div[@class='b'][1]/text()") hpri = Hpricot.parse(html) p hpri.search("//h2[text() = 'aaa111']") p hpri.search("//h2[text() = 'aaa111']/following-sibling::div") p hpri.search("//h2[text() = 'aaa111']/following-sibling::div[@class='b'][1]/text()")

実行結果

003 #<Hpricot::Elements[{elem <h3> "aaa111" </h3>}]> #<Hpricot::Elements[]> #<Hpricot::Elements[]>

    トラックバックについて
    Trackback URL:
    お気軽にどうぞ。トラックバック前にポリシーをお読みください。[policy]
    このエントリへのTrackbackにはこのURLが必要です→https://blog.cles.jp/item/3397
    Trackbacks
    このエントリにトラックバックはありません
    Comments
    愛のあるツッコミをお気軽にどうぞ。[policy]
    古いエントリについてはコメント制御しているため、即時に反映されないことがあります。
    コメントはありません
    Comments Form

    コメントは承認後の表示となります。
    OpenIDでログインすると、即時に公開されます。

    OpenID を使ってログインすることができます。

    Identity URL: Yahoo! JAPAN IDでログイン