2009-04-09 9 views
2

私はhpricotでテーブルベースのウェブサイトからいくつかの情報を抽出しようとしています。私はFireBugでXPathを手に入れました。hpricot with firebug's XPath

/html/body/div/table/tbody/tr/td/table/tbody/tr[2]/td/table/tbody/tr/td[2]/table/tbody/tr[3]/td/table[3]/tbody/tr 

これは...どうやら、放火犯のXPathは、レンダリングされたHTMLのパス、およびサイトから実際のHTMLで動作しません。私はtbodyを取り除くことで問題が解決するかもしれないと読んでいます。

私が試してみてください。

/html/body/div/table/tr/td/table/tr[2]/td/table/tr/td[2]/table/tr[3]/td/table[3]/tr 

そして、まだ動作しません...私はもう少し研究を行うと、一部の人々は、彼らは数字を削除し、そのXPathを取得する報告、私はこれを試してみてください。

/html/body/div/table/tr/td/table/tr/td/table/tr/td/table/tr/td/table/tr 

まだ運...

だから私はそれがこのようなステップバイステップで行うことを決定します

(doc/"html/body/div/table/tr").each do |aaa | 
    (aaa/"td").each do | bbb| 
     pp bbb 
     (bbb/"table/tr").each do | ccc| 
      pp ccc 
     end 
    end 
end 

私はbbbで必要な情報を見つけましたが、cccでは見つかりませんでした。

私は間違っていますか、長い/複雑なXPathでHTMLをスクラップするのに優れたツールがあります。

答えて

1

おそらく、XPathの代わりにhpricotのCSS解析を使う方がよいでしょう。 _whyはおそらく、ある時点でXPathを無効にすることについて話していました。

データのより良い例がありますか?彼らは簡単に参照されるCSSタグを使用していますか?

それは次のように検索するためにはるかに簡単です:そこhpricotを議論しました(私は今見つけることができないよう)_whyのウェブサイト上の古いページだった、とコメントのいくつかは、どのようにほのめかし

doc.search("#id_tag > table > tr.class_tag > td").each do |aaa| 
    aaa.search("blah > blah").each do |bbb| 
     bbb.inner_html 

あなたが似ているネストされた検索を実行するときは、CSSバージョンがXPathより優れた選択肢でした。

願い私はより良い答えを与えることができましたが、CSSメソッドにショットを与え、XPathであなたの髪を引き裂く前にどうなるかを真剣にお勧めします。私は今、この素晴らしいツールでCSSとI「図」、それを使用してい

1

それはNokogiriはHpricotと同じAPIを使用していますが、また、XPath式をサポートしていることは注目おそらく価値があります。

4

問題はXPather(またはFirebug XPath)にあります。 Firefox私は内部的に悪い形式のテーブルをtbody要素を持つように修正していると思いますが、HTMLには何もありません。 Nokogiriはそうしていないのですが、代わりにtrタグをテーブルの内側に置くことができます。

ので、あなたのパスは次のように鋸山になりそうだ大きなチャンスがあります:

/html/body/div/table/tr/td/table/tr[2]/td/table/tr/td[2]/table/tr[3]/td/table[3]/tr 

、それは鋸山がそれを受け入れる方法ですが:)

あなたはこの

require 'open-uri' 
require 'nokogiri' 

class String 
    def relative_to(base) 
    (base == self[0..base.length-1]) && 
     self[base.length..-1] 
    end 
end 

module Importer 
    module XUtils 
    module_function 

    def match(text, source) 
     case text 
     when String 
     source.include? text 
     when Regexp 
     text.match(source) 
     when Array 
     text.all? {|tt| source.include?(tt)} 
     else 
     false 
     end 
    end 

    def find_xpath (doc, start, texts) 
     xpath = start 
     found = true 

     while(found) 
     found = [:inner_html, :inner_text].any? do |m| 
      doc.xpath(xpath+"/*").any? do |tag| 
      tag_text = tag.send(m).strip.gsub(/[\302\240]+/, ' ') 
      if tag_text && texts.all?{|text| match(text, tag_text)} 
       xpath = tag.path.to_s 
      end 
      end 
     end 
     end 

     (xpath != start) && xpath 
    end 

    def fetch(url) 
     Nokogiri::HTML(open(url).read) 
    end 
    end 
end 
をチェックアウトする場合があります

私はこの小さなモジュールを書いて、ウェブスクレイピングとデータマイニングのときにNokogiriと協力するのを助けました。

基本的な使い方:

include XUtils 
doc = fetch("http://some.url.here") # http:// is impotrtant! 

base = find_xpath(doc, '/html/body', ["what to find1", "What to find 2"]) # when you provide array, then it'll find element conaining ALL words 

precise = find_xpath(doc, base, "what to find1") 
precise.relative_to base 

幸運

0

HTMLコードにはTBODYタグはありません。 Firebugはそれを自動的に生成します。