在此示例中,我尝试从表的<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>
代码中的所有文字?
答案 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
方法只是摆脱了前导和尾随空格。)