您可以使用XPath执行几个步骤。首先,你需要找到的table
的“水平”(即如何嵌套它是在其他表),然后找到所有后代tr
有相同数量的table
祖先:
tables = doc.xpath('//table')
tables.each do |table|
level = table.xpath('count(ancestor-or-self::table)')
rows = table.xpath(".//tr[count(ancestor::table) = #{level}]")
# do what you want with rows...
end
在更一般的情况下,在这里你可能tr
嵌套直接其它tr
S,你可以做这样的事情(这将是无效的HTML,但你可能有XML或其他一些标签):
tables.each do |table|
# Find the first descendant tr, and determine its level. This
# will be a "top-level" tr for this table. "level" here means how
# many tr elements (including itself) are between it and the
# document root.
level = table.xpath("count(descendant::tr[1]/ancestor-or-self::tr)")
# Now find all descendant trs that have that same level. Since
# the table itself is at a fixed level, this means all these nodes
# will be "top-level" rows for this table.
rows = table.xpath(".//tr[count(ancestor-or-self::tr) = #{level}]")
# handle rows...
end
第一步可以分为两个单独的查询,可能更清楚:
first_tr = table.at_xpath(".//tr")
level = first_tr.xpath("count(ancestor-or-self::tr)")
(如果有表无tr
小号虽然,这将失败,因为first_tr
将nil
。上面的组合XPath可以正确处理这种情况。)
Nokogiri实现了CSS,其中包括一些jQuery扩展,所以熟悉样式表选择器的工作方式,并且应该有更好的运气。 CSS更具可读性,但XPath更强大,因此了解这两方面都很好。在生成的HTML中很少使用'tbody'标记,但是当您查看页面HTML时,浏览器往往会将它们粘在一起。不要相信浏览器,而是直接在命令行中使用'wget'或'curl'或'nokogiri'查看HTML。如果原始HTML包含它,只能使用'tbody'。 –
@Dave:只是好奇:为什么你会接受一个答案,而不是upvote呢? –