如何使用 Nokogiri 获取标签下的所有文本?

How do I get all the text under a tag with Nokogiri?

在这个例子中,我试图从 table 的 <td> 标签中获取文本。首先,html代码。

<table>
  <tbody>
  <tr>
    <td>Single line of text</td>
  </tr>
  <tr>
    <td>Text here<p>First line</p><p>Second line</p></td>
  </tr>
  </tbody>
</table>

然后ruby代码在这里。

require 'nokogiri'
require 'pp'

html = File.open('test.html').read
doc = Nokogiri::HTML(html)
rows = doc.xpath('//table[1]/tbody/tr')

data = rows.collect do |row|
  row.at_xpath('td[1]/text()').to_s
end

pp data

我得到的结果是。

["Single line of text", "Text here"]

如何获取第二个 <td> 标签中的所有文本?

您需要进行两项更改才能获得所有 text 节点。首先 at_xpath 只会 return 一个节点,因此要获得多个节点,您需要使用 xpath.

其次,要获取所有后代节点,而不仅仅是子节点,请使用 // 而不是 /

结合这些,代码行将是:

row.xpath('td[1]//text()').to_s

这会将所有文本节点连接在一起,给出结果:

["Single line of text", "Text hereFirst lineSecond line"]

这可能不是您想要的。您需要处理以满足您的需要,而不仅仅是在生成的节点集上调用 to_s

这个怎么样?

pp doc.search("//tr[2]//td//text()").map { |item| item.text }

正如 matt 所说,您可以使用 //.

获取所有后代

如果您特别需要第二个 tr,也可以将其编入索引。只需省略索引即可获得所有 trs.

并且您可以过滤生成的文本对象以仅获取具有 td 上游的对象。

最后,映射每个 Nokogiri 对象,将文本提取到最终数组中,如下所示:

["Text here", "First line", "Second line"]

如果您想获取任何元素的所有文本,您需要 Nokogiri::XML::Nodetext 方法:

p doc.xpath('//table[1]/tbody/tr').map{ |tr| tr.text.strip }
#=> ["Single line of text", "Text hereFirst lineSecond line"]

strip 方法只是去除了前导和尾随空格。)