2017-02-27 57 views
0

带有自定义属性我有HTML与身体看起来像:如何得到div元素使用引入nokogiri

<body> 
    <div class="myclass" dd:meta1="meta data 1" dd:meta2="CD5503253E54"></div> 
    <div class="myclass" dd:meta1="meta data 11"></div> 
</body> 

我想在上面身上所有的div元素,这将有dd:meta2属性,所以,我只会得到一个div。

我写了代码来获取div元素,但我收到一个错误,看起来像它与我在属性中的:有关。

我的逻辑:

page = Nokogiri::HTML(html_string) 
meta_data_divs = page.css('body').css("div[dd:meta2]") 

错误:

unexpected ':' after '#<Nokogiri::CSS::Node:0x007fac6b986d58>' 

如何处理 ':' 在属性?

回答

0

看起来Nokogiri不知道如何处理命名空间参数。下面是得到同样结果的另一种方法:这将返回所有div节点与dd:meta2参数

require 'nokogiri' 

doc = Nokogiri::HTML(<<EOT) 
<body> 
    <div class="myclass" dd:meta1="meta data 1" dd:meta2="CD5503253E54"></div> 
    <div class="myclass" dd:meta1="meta data 11"></div> 
</body> 
EOT 

doc.search('div').select{ |div| div.attributes.include?('dd:meta2') } 
# => [#(Element:0x3fea99895530 { 
#  name = "div", 
#  attributes = [ 
#   #(Attr:0x3fea99895508 { name = "class", value = "myclass" }), 
#   #(Attr:0x3fea998954f4 { name = "dd:meta1", value = "meta data 1" }), 
#   #(Attr:0x3fea998954e0 { name = "dd:meta2", value = "CD5503253E54" })] 
#  })] 

同样,你可以使用相同的用.first上涨了年底要像at,但它不会是一样快:

doc.search('div').find{ |div| div.attributes.include?('dd:meta2') } 
# => #(Element:0x3fea99895530 { 
#  name = "div", 
#  attributes = [ 
#  #(Attr:0x3fea99895508 { name = "class", value = "myclass" }), 
#  #(Attr:0x3fea998954f4 { name = "dd:meta1", value = "meta data 1" }), 
#  #(Attr:0x3fea998954e0 { name = "dd:meta2", value = "CD5503253E54" })] 
#  }) 

这将是比你如何试图它慢一点因为它会导致解析器搜索整个文档并返回所有div标签,那么Ruby将不得不筛选结果以找到具有所需参数的节点。但它会比引发异常的代码快得多。

我建议向Nokogiri团队提交一份错误报告,向他们展示问题。


嘿,写一个我做了搜索dd:meta2跑进your question on Nokogiri-Talk具有到引入nokogiri神解释发生了什么答案,并具有我建议同样的解决方案之后。所以你有它。

0

我刚刚在昨天做了这个。这里是我的html:

<div data-purpose="video-length">[^>]+<\/div> 

这里是我的引入nokogiri表达:

page.parser.css("div[data-purpose=video-length]").first.try(:text).try(:strip) 

这花了我从div标签里想出来的价值和剥下的超额收益。使用.try调用的原因是跳过必须让if语句在返回nil时处理。这里的秘密在于在.css表达式中使用[]:div [data-purpose = video-length]。