【问题标题】:Parsing the previous <td> of an element (ignoring other elements inbetween)解析元素的前一个 <td> (忽略中间的其他元素)
【发布时间】:2016-04-12 10:15:12
【问题描述】:

我有一个非常长的 HTML 文件,其中包含许多不同的表格。我只想解析某些表,但不幸的是 &lt;table&gt; 标记在这里没有帮助。

我想要解析的表如下所示:

<tr>
<td> TEXT1 </td>
<td> <a class='unique identifier' ...> TEXT2 </a></td>
</tr>

我想要“TEXT1”和“TEXT2”。我知道如何获取“TEXT2”:它总是在 &lt;a&gt; 标签中,到目前为止我的解决方案是

//a[(@class="unique identifier")]

注意:有时“TEXT1”在&lt;p&gt; 标签中,有时不在。有时在它之后还有其他标签,如&lt;b&gt;s 或&lt;br&gt;s 或&lt;em&gt; 等。我认为我需要在我找到的每个&lt;a&gt; 之后获取以前的&lt;td&gt; 内容,但忽略介于两者之间的任何其他元素。

我怎样才能告诉 Nokogiri,对于我发现的每个“TEXT2”,也可以返回并获取之前的 &lt;td&gt;,以便我可以获取“TEXT1”?

【问题讨论】:

  • 这是怎么复制的?
  • 在那里你可能会找到获取tr元素的方法
  • 这不是我的问题。你读过我问的吗?
  • 是的。要获取这两个文本,您需要一种上树的方法(回到“a”的父级),这样当您到达 tr 时,您将拥有两个 td,因此您将能够访问这两个文本。这不是你想要的吗?
  • 对不起。尽管存在同样的问题,但该问题的答案并不符合您的需求。

标签: ruby html-parsing nokogiri


【解决方案1】:

我会这样做:

require 'nokogiri'

doc = Nokogiri::HTML(<<EOT)
<tr>
<td> TEXT1 </td>
<td> <a class='uid'> TEXT2 </a></td>
</tr>
EOT

wrapping_tr = doc.at('//a[@class="uid"]/../..')
nodes = wrapping_tr.search('td')

nodes.map(&:text) 
# => [" TEXT1 ", "  TEXT2 "]

我建议花时间阅读the XPath documentation,因为这是非常初级的。

【讨论】:

  • 非常感谢!但是:如果在wrapping_tr 中有我的//a[@class="uid"],那我为什么还要再找一个&lt;td&gt; within 呢?还是我错过了什么? puts 只给我&lt;a class='uid'&gt; TEXT2 &lt;/a&gt;
  • "If in 'wrapping_tr' there is my '//a[@class="uid"]'" 所以您是说您的示例不准确且不足以解释问题?你读过“minimal reproducible example”吗?
  • 不,你引用的很完美。但似乎我们随后在&lt;a class='uid'&gt; TEXT2 &lt;/a&gt;&lt;/td&gt; 中搜索&lt;td&gt;。但我们不需要更深入,但可以这么说。你明白我的意思吗,还是我误解了什么?再次感谢您,作为初学者,您在这里帮了我很多忙!
  • 示例代码的输出是否显示了您要求的结果?如果是这样,那么它似乎做了正确的事情。如果是这样,您可能应该阅读文档,尤其是关于 //.. 在 XPaths 中的工作方式,因为它们是这样做的关键。
  • 嘿!不,不是的。 wrapping_tr = doc.at('//a[(@class="uid")]') 给了我&lt;a class='uid'&gt; TEXT2 &lt;/a&gt;。之后的所有内容都没有任何内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-18
  • 1970-01-01
  • 2017-05-09
  • 2020-01-21
  • 2021-11-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多