html - 如何在抓取时避免加入节点中的所有文本



ruby xml (1)

这是一个容易解决的问题,这是因为没有阅读有关 text 在NodeSet和Node(或Element)上使用时的行为方式的文档。

NodeSet文档 text 将:

获取所有包含的Node对象的内部文本

这是我们所看到的:

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

doc.search('p').text # => "foobarbaz"

因为:

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

相反,我们想要获取每个节点并提取其文本:

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

可以使用 map 完成:

doc.search('p').map { |node| node.text } # => ["foo", "bar", "baz"]

Ruby允许我们使用以下内容更简洁地编写:

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

无论我们使用的是HTML还是XML,同样的事情都适用,因为HTML是一种更宽松的XML版本。

Node有几种别名方法可以获取其嵌入的文本。 从 文档

#content ⇒ Object

也称为: textinner_text

返回此节点的内容。

当我从HTML或XML中抓取几个相关节点以提取文本时,所有文本都被连接成一个长字符串,从而无法恢复单个文本字符串。

例如:

require 'nokogiri'

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

doc.search('p').text # => "foobarbaz"

但我想要的是:

["foo", "bar", "baz"]

抓取XML时会发生同样的情况:

doc = Nokogiri::XML(<<EOT)
<root>
  <block>
    <entries>foo</entries>
    <entries>bar</entries>
    <entries>baz</entries>
  </block>
</root>
EOT

doc.search('entries').text # => "foobarbaz"

为什么会发生这种情况,我该如何避免呢?





nokogiri