如何一次访问一个标记

我有以下HTML:

Some words.

Some more words.

Even more words.

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

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

并运行

 doc.css('#test_id').text 

在控制台我得到:

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

我如何才能获得第一个

元素?


我想我和.children一起.children

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

这是正确的方法吗?

问题是你没有在正确类型的对象上使用text

如果你正在查看NodeSet text文档说:

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

如果您正在查看Node AKA Element,它会说:

返回此节点的内容

这是区别:

 require 'nokogiri' doc = Nokogiri::HTML(< 

Some words.

Some more words.

Even more words.

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 # => [#, #]>, #, #]>, #, #]>, #] doc.search('#test_id').children[0] # => # doc.search('#test_id').children[1] # => #]> 

与:

 doc.search('#test_id p') # => [#]>, #]>, #]>] doc.search('#test_id p')[0] # => #]> doc.search('#test_id p')[1] # => #]> 

请注意子项如何在用于格式化HTML的标记之间返回文本节点。 您必须知道, children将返回所选标记下方的HTML中的所有内容 。 这有时很有用,但对于一般的文本检索,它可能不是你想要的。

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

你也可以试试这个。

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

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