hpricot与firebug的XPath

我正在尝试使用hpricot从基于表的网站中提取一些信息。 我用FireBug获得了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 

这不起作用……显然,FireBug的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。

您的问题出在XPather(或firebug XPath)中。 Firefox我认为在内部修复格式错误的表格,即使在HTML中也没有。 Nokogiri没有这样做,相反它允许tr标签在表内。

所以你的路径看起来很像这样的nokogiri:

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

这就是nokogiri如何接受它:)

你可能想看看这个

 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 

祝好运

你可能最好使用hpricot的CSS解析而不是XPath。 _Why正在讨论可能在某一时刻删除XPath。

你有更好的数据示例吗? 他们使用容易引用的css标签吗?

搜索更容易:

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

在_why的网站上有一个较旧的页面(我现在似乎无法找到)正在讨论hpricot,并且一些评论暗示了在进行类似于你的嵌套搜索时,CSS版本是如何比XPath更好的选择。

希望我能给出一个更好的答案,但我认真地建议给一个CSS方法一个镜头,看看它如何用XPath撕掉你的头发。

我现在正在使用css,我用这个伟大的工具“找到它”: http://www.selectorgadget.com

值得注意的是, Nokogiri使用与Hpricot相同的API,但也支持XPath表达式。

您的HTML代码中没有TBODY标记。 Firebug会自动生成它。