【问题标题】:How to get div elements with custom attributes using Nokogiri如何使用 Nokogiri 获取具有自定义属性的 div 元素
【发布时间】:2017-02-27 20:18:55
【问题描述】:

我的 HTML 的正文看起来像:

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

我想获取所有具有dd:meta2 属性的 div 元素,所以在上面的正文中,我将只获取一个 div。

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

我的逻辑:

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

错误:

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

如何处理属性中的':'?

【问题讨论】:

    标签: html css ruby nokogiri


    【解决方案1】:

    我实际上是昨天才这样做的。这是我的html:

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

    这是我的 nokogiri 表达:

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

    这从 div 标签中取出了我想要的值,并剥离了额外的回报。使用 .try 调用的原因是在返回 nil 时跳过必须处理 if 语句。这里的秘密在于在 .css 表达式中使用 []:div[data- purpose=video-length]。

    【讨论】:

      【解决方案2】:

      看起来 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" })]
      #       })]
      

      这将返回所有带有dd:meta2 参数的div 节点。

      同样,您可以使用相同的 .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 神的答案,解释了正在发生的事情,这与我建议的解决方案相同。所以你有它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-08-11
        • 2023-02-25
        • 1970-01-01
        • 2020-12-13
        • 1970-01-01
        • 2023-03-08
        • 2021-11-21
        • 1970-01-01
        相关资源
        最近更新 更多