【问题标题】:Using Nokogiri to find element before another element使用 Nokogiri 在另一个元素之前查找元素
【发布时间】:2015-06-02 13:23:57
【问题描述】:

我有一个部分 HTML 文档:

<h2>Destinations</h2>
<div>It is nice <b>anywhere</b> but here.
<ul>
  <li>Florida</li>
  <li>New York</li>
</ul>
<h2>Shopping List</h2>
<ul>
  <li>Booze</li>
  <li>Bacon</li>
</ul>

在每个 &lt;li&gt; 项目上,我想知道项目所在的类别,例如,&lt;h2&gt; 标记中的文本。

这段代码不起作用,但这是我想要做的:

@page.search('li').each do |li|
  li.previous('h2').text
end

【问题讨论】:

  • 这将是 li 父级之前的 h2,而不是 li 之前的 h2,不是吗?
  • 我真的不知道h2和li之间会有多少个元素;我只想知道如何在使用 Mechanize 搜索找到的 li 之前找到 h2。
  • 您正在倒退,而不是迭代 li 并尝试获取前面的 h2,迭代 h2 然后获取 li
  • @pguardiario 做到了。搜索&lt;h2&gt; 标签,然后查看下一个兄弟并使用它来下降到&lt;li&gt; 标签。

标签: ruby nokogiri screen-scraping


【解决方案1】:

你很接近。

@page.search('li').each do |li|
  category = li.xpath('../preceding-sibling::h2').text
  puts "#{li.text}: category #{category}" 
end

【讨论】:

    【解决方案2】:

    Nokogiri 允许您使用xpath 表达式来定位元素:

    categories = []
    
    doc.xpath("//li").each do |elem|
      categories << elem.parent.xpath("preceding-sibling::h2").last.text
    end
    
    categories.uniq!
    p categories
    

    第一部分查找所有“li”元素,然后在里面,我们查找父元素 (ul, ol),查找之前的元素 (preceding-sibling),它是一个 h2。可能不止一个,所以我们取最后一个(即最接近当前位置的那个)。

    我们需要调用“uniq!”因为我们得到了每个 'li' 的 h2(因为 'li' 是起点)。

    使用您自己的 HTML 示例,此代码输出:

    ["Destinations", "Shopping List"]
    

    【讨论】:

    • 因为它实际上是我感兴趣的 li 元素,有没有办法返回直到找到 h2,或者加倍前面的元素指令?或者,我是否必须从 ul 开始编程并向上,然后对 ul 中的所有 li 元素进行循环?
    • 使用 li 有什么好处?你周围确实有一个 ul,而且它是一个。它可以与 li 一起使用,但你会有很多重复
    • OP 有自己的理由来指定需要&lt;li&gt; 标签。也许他们希望能够在其中插入额外的内容?
    • 尽我所能更新
    • 这很好用。还要感谢您提供 XPath Axes 教程的链接;我曾尝试搜索 Nokogiri 和 Mechanize 文档,但找不到您从哪里获得“前兄弟”。
    【解决方案3】:

    代码:

    categories = []
    Nokogiri::HTML("yours HTML here").css("h2").each do |category|
            categories << category.text
          end
    

    结果:

    categories = ["Destinations", "Shopping List"] 
    

    【讨论】:

    • 为什么不解释为什么它有效,而不是仅仅抛出一些代码希望 OP 能解决这个问题?我们作为回答者的工作实际上是教育,而不仅仅是解决眼前的问题。
    • 改用categories = Nokogiri::HTML("yours HTML here").css("h2").map(&amp;:text)
    猜你喜欢
    • 1970-01-01
    • 2016-01-21
    • 1970-01-01
    • 1970-01-01
    • 2020-03-23
    • 1970-01-01
    • 1970-01-01
    • 2020-06-15
    • 1970-01-01
    相关资源
    最近更新 更多