如何一次访问多个 <p> 标签

How to access multiple <p> tags one at a time

我有以下 HTML:

<div id="test_id">
    <p>Some words.</p>
    <p>Some more words.</p>
    <p>Even more words.</p>
</div>

如果我使用以下方法解析 HTML:

doc = Nokogiri::HTML(open("http://my_url"))

和运行

doc.css('#test_id').text

在控制台中我得到:

=> "Some words.\nSome more words.\nEven more words"

如何只获取第一个 <p> 元素?


我想我用 .children

弄明白了
doc.css('#test_id').children[0].text

这是正确的方法吗?

你也可以试试这个。

$("p:first-child").text();

这将为您提供任何父元素的所有第一个子元素。所以对于你的例子它应该工作

问题是您没有对正确类型的对象使用 text

如果您正在查看 NodeSettext 文档说:

Get the inner text of all contained Node objects

如果您正在查看 Node AKA 元素,它会显示:

Returns the content for this Node

区别如下:

require 'nokogiri'

doc = Nokogiri::HTML(<<EOT)
<div id="test_id">
    <p>Some words.</p>
    <p>Some more words.</p>
    <p>Even more words.</p>
</div>
EOT

doc.search('p').class  # => Nokogiri::XML::NodeSet
doc.search('p').text  # => "Some words.Some more words.Even more words."

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

at 就像 search(...).first.

通常,如果我们想要 NodeSet 的文本,我们会使用:

doc.search('p').map(&:text)  # => ["Some words.", "Some more words.", "Even more words."]

这使得选择特定节点的文本变得容易。

另见“”。

doc.css('#test_id').children[0].text

嗯,是的,你可以这样做,但是 children 不会做同样的事情:

doc.search('#test_id').children
# => [#<Nokogiri::XML::Text:0x3fc31580ca24 "\n    ">, #<Nokogiri::XML::Element:0x3fc315103714 name="p" children=[#<Nokogiri::XML::Text:0x3fc31580d5a0 "Some words.">]>, #<Nokogiri::XML::Text:0x3fc315107f44 "\n    ">, #<Nokogiri::XML::Element:0x3fc3151036ec name="p" children=[#<Nokogiri::XML::Text:0x3fc315107cc4 "Some more words.">]>, #<Nokogiri::XML::Text:0x3fc315107b20 "\n    ">, #<Nokogiri::XML::Element:0x3fc3151036c4 name="p" children=[#<Nokogiri::XML::Text:0x3fc3151078a0 "Even more words.">]>, #<Nokogiri::XML::Text:0x3fc3151076fc "\n">]
doc.search('#test_id').children[0] # => #<Nokogiri::XML::Text:0x3fc31580ca24 "\n    ">
doc.search('#test_id').children[1] # => #<Nokogiri::XML::Element:0x3fc315103714 name="p" children=[#<Nokogiri::XML::Text:0x3fc31580d5a0 "Some words.">]>

对比:

doc.search('#test_id p')
# => [#<Nokogiri::XML::Element:0x3fc315103714 name="p" children=[#<Nokogiri::XML::Text:0x3fc31580d5a0 "Some words.">]>, #<Nokogiri::XML::Element:0x3fc3151036ec name="p" children=[#<Nokogiri::XML::Text:0x3fc315107cc4 "Some more words.">]>, #<Nokogiri::XML::Element:0x3fc3151036c4 name="p" children=[#<Nokogiri::XML::Text:0x3fc3151078a0 "Even more words.">]>]
doc.search('#test_id p')[0] # => #<Nokogiri::XML::Element:0x3fc315103714 name="p" children=[#<Nokogiri::XML::Text:0x3fc31580d5a0 "Some words.">]>
doc.search('#test_id p')[1] # => #<Nokogiri::XML::Element:0x3fc3151036ec name="p" children=[#<Nokogiri::XML::Text:0x3fc315107cc4 "Some more words.">]>

注意 children 如何返回用于格式化 HTML 的标签之间的文本节点。您必须注意 children returns everything 在 HTML 中所选标签下方。这有时很有用,但对于一般的文本检索,它可能不是您想要的。

相反,使用更具选择性的 '#test_id p' 选择器并迭代返回的 NodeSet,您将避免格式化文本节点,并且在 NodeSet 中使用切片或索引时不必考虑它们.