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

How to get text after tag within li element

我试图在包含 "Inhalt:".

span 元素的帮助下识别的 <li> 元素中获取文本

我要获取的文本是“0,75l”。

这是 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()')

您正在尝试查找 <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 returns 一个 NodeSet,这将是文档中所有匹配的节点。虽然这种特殊用途可能只出现一次 "Inhalt:",但在另一个包含多个目标词实例的文档中,您会得到多次匹配并得到垃圾结果。
  • parent 不是 NodeSet 的方法,所以它会爆炸。
  • parent.xpath 不是继续选择器的好方法。相反,要在 XPath 中完成此操作,您应该使用类似的东西:

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

    .. 表示移动到 XPath-lingo 中当前节点的父节点。这超出了我的脑海,但看起来不错。


Why do you use at instead of .css or .xpath?

at 等同于 search('some_selector').first,因此找到该选择器第一次出现的位置是 shorthand。 atsearch 是通用方法,采用 XPath 或 CSS,并依靠一些试探法来确定选择器是 XPath 还是 CSS 字符串。他们 可以 被愚弄,但大多数时候他们是完全安全的,并且比 xpathcssat_xpathat_css 变体。

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

我们看到人们经常摔倒,这让人感到困惑。 atat_* 变体 return 一个节点,search 及其 xpathcss 变体 return 一个节点集。当试图从搜索中提取文本时 text 会做一些意想不到的事情。默想一下:

require 'nokogiri'

doc = Nokogiri::HTML(<<EOT)
<html>
  <body>
    <p>foo</p>
    <p>bar</p>
  </body>
</html>
EOT

doc.search('p').class # => Nokogiri::XML::NodeSet
doc.search('p').text # => "foobar"

doc.at('p').class # => Nokogiri::XML::Element
doc.at('p').text # => "foo"

doc.search('p').map(&:text) # => ["foo", "bar"]

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

另见“”。