如何一次访问多个 <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
。
如果您正在查看 NodeSet,text
文档说:
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 中使用切片或索引时不必考虑它们.
我有以下 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
。
如果您正在查看 NodeSet,text
文档说:
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 中使用切片或索引时不必考虑它们.