ruby - hpricot 与 Firebug 的 XPath

标签 ruby xpath firebug hpricot

我正在尝试使用 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 正在内部修复格式错误的表格以具有 tbody 元素,即使在 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

祝你好运

关于ruby - hpricot 与 Firebug 的 XPath,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/734178/

相关文章:

mysql - 在 Rails Controller 操作中创建 Mysql 用户

ruby - 为散列生成缓存键(唯一键)

PHP DOM previousSibling 不起作用

java - 如何通过 Selenium 通过 XPath 访问 WebElement?

python - Scrapy:从网站上抓取所有文本,但不抓取超链接的文本

javascript - Firefox 中的缓存未清除

ruby-on-rails - validates_associated 和 validates_presence_of 没有按预期与 rspec 一起工作?

javascript - 从 "FIREBUG"保护 jquery 脚本?

css - firebug 不显示特定于浏览器的 css 声明。

ruby-on-rails - 为什么Rails应用程序在Docker中的加载速度非常慢?