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

时间:2016-05-10 22:46:17

标签: html ruby xpath nokogiri

在此示例中,我尝试从表的<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>

然后是红宝石代码。

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>代码中的所有文字?

3 个答案:

答案 0 :(得分:3)

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

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

结合这些,代码行将是:

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

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

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

这可能不是你想要的。

,而不是仅仅在生成的节点集上调用to_s,而是需要进行处理。

答案 1 :(得分:0)

这个怎么样?

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

正如亚特所说,你可以使用//获得所有后代。

如果您想要特定的第二个tr,也可以对其进行索引。只需省略索引即可获得所有tr s。

您可以过滤生成的文本对象,只获得那些上游td的文本对象。

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

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

答案 2 :(得分:0)

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

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

strip方法只是摆脱了前导和尾随空格。)