我正在尝试使用<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()')
答案 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
,因此它是查找该选择器第一次出现的简写。 at
和search
是通用方法,采用XPath或CSS,并依赖一些启发式方法来确定选择器是XPath还是CSS字符串。他们可以被愚弄,但大部分时间他们比xpath
,css
,at_xpath
或{{1}更安全,更方便变种。
如果标记可能包含您要识别的多个节点,请相应地调整at_css
和at
的使用。
我们看到人们经常摔倒,这有点混乱。 search
和at
变体返回一个节点,at_*
及其search
和xpath
变体返回一个NodeSet。当尝试从搜索css
中提取文本时,会做出意想不到的事情。冥想:
text
此行为已记录在案,但人们很少阅读该信息,然后尝试弄清楚如何在两个节点被修复后恢复它们的文本。
参见&#34; How to avoid joining all text from Nodes when scraping&#34;还