我正在尝试使用Nokogiri来解析一个带有一些相当古怪的标记的HTML文件。具体来说,我正在尝试抓取同时定义了id,多个类和样式的div。标记看起来像这样:
<div id="foo">
<div id="bar" class="baz bang" style="display: block;">
<h2>title</h2>
<dl>
List of stuff
</dl>
</div>
</div>
我正试图抓住位于问题div内的<dl>
。我可以使用单个id属性获得没有问题的div,但是我无法想出让Nokogiri用id 和类来获取div的方法。所以这些工作正常:
content = @doc.xpath("//div[id='foo']")
content = @doc.css('div#foo')
但这些不会返回任何内容:
content = @doc.xpath("//div[id='bar']")
content = @doc.xpath("div#bar")
我有什么明显的遗漏吗?
答案 0 :(得分:4)
我可以通过一个id获得div 属性没有问题,但我不能 找出一种获得Nokogiri的方法 用两个ID抓住div 类。
你想要:
//div[id='bar' and class='baz bang' and style='display: block;']
答案 1 :(得分:2)
以下适用于我。
require 'rubygems'
require 'nokogiri'
html = %{
<div id="foo">
<div id="bar" class="baz bang" style="display: block;">
<h2>title</h2>
<dl>
List of stuff
</dl>
</div>
</div>
}
doc = Nokogiri::HTML.parse(html)
content = doc
.xpath("//div[@id='foo']/div[@id='bar' and @class='baz bang']/dl")
.inner_html
puts content
答案 2 :(得分:1)
我认为content = @doc.xpath("div#bar")
是一个拼写错误,应该是content = @doc.css("div#bar")
或更好content = @doc.css("#bar")
。第二个代码块中的第一个表达式似乎没问题。
答案 3 :(得分:1)
您写道:
我正试图抓住那些拥有的div 两个ID,多个类和样式 定义
并且
我正试图抓住问题div中的
<dl>
所以,这个XPath 1.0:
//div[@id][contains(normalize-space(@class),' ')][@style]/dl
答案 4 :(得分:0)
我强烈建议使用CSS选择器而不是XPath作为起点,因为CSS更具可读性,并且不太可能导致视觉噪音。
require 'nokogiri'
doc = Nokogiri::HTML(<<EOT)
<div id="foo">
<div id="bar" class="baz bang" style="display: block;">
<h2>title</h2>
<dl>
List of stuff
</dl>
</div>
</div>
EOT
解析后,使用CSS查找<div ... id="foo">
:
doc.at('div#foo').to_html
# => "<div id=\"foo\">\n" +
# " <div id=\"bar\" class=\"baz bang\" style=\"display: block;\">\n" +
# " <h2>title</h2>\n" +
# " <dl>\n" +
# " List of stuff\n" +
# " </dl>\n" +
# " </div>\n" +
# "</div>"
还有<div id="bar">
:
doc.at('div#bar').to_html
# => "<div id=\"bar\" class=\"baz bang\" style=\"display: block;\">\n" +
# " <h2>title</h2>\n" +
# " <dl>\n" +
# " List of stuff\n" +
# " </dl>\n" +
# " </div>"
我们可以搜索具有两个类名称的标签:
doc.at('.baz.bang').to_html
# => "<div id=\"bar\" class=\"baz bang\" style=\"display: block;\">\n" +
# " <h2>title</h2>\n" +
# " <dl>\n" +
# " List of stuff\n" +
# " </dl>\n" +
# " </div>"
我们可以查找带有两个类及其嵌入式<dl>
标签的显式div:
doc.at('div.baz.bang dl').to_html
# => "<dl>\n" +
# " List of stuff\n" +
# " </dl>"
或者甚至通过ID和类别:
doc.at('div#bar.baz.bang').to_html
# => "<div id=\"bar\" class=\"baz bang\" style=\"display: block;\">\n" +
# " <h2>title</h2>\n" +
# " <dl>\n" +
# " List of stuff\n" +
# " </dl>\n" +
# " </div>"
使用<dl>
:
doc.at('div#bar.baz.bang dl').to_html
# => "<dl>\n" +
# " List of stuff\n" +
# " </dl>"
我正在使用at
,与使用search(...some selector...).first
等效。 Nokogiri支持search
和css
和xpath
,它们是CSS和XPath的变体,并且返回NodeSet以及at
,at_css
和{{1} },它返回一个Node。了解“ NodeSet
”和“ Node”之间的区别以及它们与at_xpath
和Searchable
的关系非常重要,因此请阅读文档。