获取特定索引nokogiri中的元素



如何获取索引2处的元素。

例如,在下面的HTML中,我想显示第三个元素,即DIV:

<HTMl>
    <DIV></DIV>
    <OL></OL>
    <DIV> </DIV>
</HTML>

我一直在尝试以下内容:

p1 =  html_doc.css('body:nth-child(2)')
puts p1

我不认为你理解我们如何使用像Nokogiri这样的解析器,因为它比你想象的要容易得多。

我会使用:

require 'nokogiri'
doc = Nokogiri::HTML(<<EOT)
<HTMl>
    <DIV>1</DIV>
    <OL></OL>
    <DIV>2</DIV>
</HTML>
EOT
doc.at('//div[2]').to_html # => "<div>2</div>"

这是使用at,它返回与选择器匹配的第一个Node。//div[2]是一个XPath选择器,它将返回找到的第二个<div>。可以使用search而不是at,但它返回一个NodeSet,它就像一个数组,这意味着我需要提取那个特定的节点。

或者,我可以使用CSS而不是XPath:

doc.search('div:nth-child(3)').to_html # => "<div>2</div>"

对我来说,就可读性而言,这并不是对XPath的真正改进。

使用search查找特定标签的所有出现,意味着我必须从返回的NodeSet:中选择特定元素

doc.search('div')[1].to_html # => "<div>2</div>"

或者:

doc.search('div').last.to_html # => "<div>2</div>"

以这种方式使用search的缺点是,它在大型文档上会更慢,而且不必要地占用内存,因为search会找到文档中所有与选择器匹配的节点,然后在只选择一个节点后将其丢弃。searchcssxpath的行为都是这样的,因此,如果您只需要第一个匹配节点,请使用at或其等效的at_cssat_xpath,并提供一个足够明确的选择器来查找您想要的标签。

根据":nth-child()"以及我对其工作原理的理解,'body:nth-child(2)'不起作用是因为你没有正确使用它。nth-child查看所提供的标记,并在其父级下找到该标记的"第n个"出现。因此,您要求在body的"html"父级下提供第三个标记,但它不存在,因为格式正确的html文档是:

<html>
  <head></head>
  <body></body
</html>

(如何告诉Nokogiri解析文档决定了生成的DOM的结构。)

相反,使用:div:nth-child(3),它表示"查找div的父级的第三个子级,即"body",并生成第二个div标记。

回到Nokogiri如何被告知解析文档;思考这些之间的区别:

doc = Nokogiri::HTML(<<EOT)
<p>foo</p>
EOT
puts doc.to_html
# >> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
# >> <html><body>
# >> <p>foo</p>
# >> </body></html>

和:

require 'nokogiri'
doc = Nokogiri::HTML::DocumentFragment.parse(<<EOT)
<p>foo</p>
EOT
puts doc.to_html
# >> <p>foo</p>

如果您可以修改HTML,则添加id和类以轻松地针对您要查找的内容(还添加body标记)。

如果不能修改HTML,请保持选择器的简单性,并访问数组的第二个元素。

html_doc.css('div')[1]

相关内容

  • 没有找到相关文章

最新更新