Html 如何使用Nokogiri获取具有自定义属性的div元素

Html 如何使用Nokogiri获取具有自定义属性的div元素,html,css,ruby,nokogiri,Html,Css,Ruby,Nokogiri,我有HTML,其主体看起来像: <body> <div class="myclass" dd:meta1="meta data 1" dd:meta2="CD5503253E54"></div> <div class="myclass" dd:meta1="meta data 11"></div> </body> 错误: unexpected ':' after '#<Nokogiri::CSS::Nod

我有HTML,其主体看起来像:

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

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

如何处理属性中的“:”?

看起来Nokogiri不知道如何处理命名空间参数。以下是获得相同结果的另一种方法:

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" })]
#       })]
这将比您尝试的要慢一点,因为这将导致解析器搜索整个文档并返回所有div标记,然后Ruby将不得不筛选结果以找到具有所需参数的节点。但它比引发异常的代码要快得多

我建议向Nokogiri团队提交一份bug报告,向他们展示问题所在


呵呵,在写了这篇文章之后,我搜索了dd:meta2,找到了Nokogiri神的答案,解释了发生了什么,这和我建议的解决方案是一样的。好了。我昨天才做的。这是我的html:

<div data-purpose="video-length">[^>]+<\/div>
这从div标签中取出了我想要的值,并去掉了额外的返回值。使用.try调用的原因是在返回nil时不必处理if语句。这里的秘密在于在.css表达式中使用[]:div[data purpose=video length]

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 data-purpose="video-length">[^>]+<\/div>
page.parser.css("div[data-purpose=video-length]").first.try(:text).try(:strip)