如何在li元素中的标记之后获取文本

时间:2016-10-07 19:09:38

标签: ruby-on-rails ruby xml-parsing nokogiri

我正在尝试使用<li>元素帮助识别span元素中的文本,该元素包含&#34; Inhalt:&#34;。

我想要的文字是&#34; 0,75l&#34;。

这是HTML代码:

<li class="product--tax is-left">
   <span class="label--purchase-unit">Inhalt:</span>
0,75 l #text I want to get
</li>

如果尝试过这个,但它似乎不起作用:

doc.search("[text()*='Inhalt:']").parent.xpath('text()')

1 个答案:

答案 0 :(得分:1)

您正在尝试查找<span>后面的文本节点。一旦你知道<span>在哪里:

,这很容易做到
require 'nokogiri'

doc = Nokogiri::HTML(<<EOT)

<li class="product--tax is-left">
   <span class="label--purchase-unit">Inhalt:</span>
0,75 l
</li>
EOT

这些是实现目标的各种方式:

doc.at('li span').next_sibling.text.strip # => "0,75 l"
doc.at('li.product--tax span.label--purchase-unit').next_sibling.text.strip # => "0,75 l"
doc.at('.label--purchase-unit').next_sibling.text.strip # => "0,75 l"
doc.at('span.label--purchase-unit').next_sibling.text.strip # => "0,75 l"

继续......

doc.search("[text()*='Inhalt:']").parent.xpath('text()')

是尝试查找节点的不好方法:

  • search返回一个NodeSet,它将是文档中所有匹配的节点。虽然这种特殊用途可能只有一次&#34; Inhalt:&#34;,但在另一个包含目标词的多个实例的文档中,您将获得多次点击并获得垃圾结果。
  • parent不是NodeSet的一种方法,因此会爆炸。
  • parent.xpath不是继续选择器的好方法。相反,要在XPath中实现这一点,您应该使用类似的东西:

    [text()*='Inhalt:']/../text()
    

    ..表示移至XPath-lingo中当前节点的父节点。这不是我的头脑,但看起来是正确的。

  

为什么使用at而不是.css或.xpath?

at相当于search('some_selector').first,因此它是查找该选择器第一次出现的简写。 atsearch是通用方法,采用XPath或CSS,并依赖一些启发式方法来确定选择器是XPath还是CSS字符串。他们可以被愚弄,但大部分时间他们比xpathcssat_xpath或{{1}更安全,更方便变种。

如果标记可能包含您要识别的多个节点,请相应地调整at_cssat的使用。

我们看到人们经常摔倒,这有点混乱。 searchat变体返回一个节点,at_*及其searchxpath变体返回一个NodeSet。当尝试从搜索css中提取文本时,会做出意想不到的事情。冥想:

text

此行为已记录在案,但人们很少阅读该信息,然后尝试弄清楚如何在两个节点被修复后恢复它们的文本。

参见&#34; How to avoid joining all text from Nodes when scraping&#34;还