【问题标题】:Nokogiri/Mechanize xpath locator breaks when there is a stray start tag当有一个杂散的开始标签时,Nokogiri/Mechanize xpath 定位器会中断
【发布时间】:2012-10-09 03:15:07
【问题描述】:

我使用 Mechanize 加载了一个页面:

url = 'http://www.blah.com'
agent = Mechanize.new
page = agent.get(url)

并尝试使用 XPath 选择器访问元素:

found = page.at('/html/body/table')

它返回nil,因为我无法控制的 HTML 有一个不应该出现的开始标签:

<html>
  <body>
    <tr>
    <table>
      . . .

当浏览器在现实生活中呈现页面时,Firefox 称之为“杂散开始标记”,它会被忽略(Firefox 给了我忽略它的 xpath),但 Nokogiri 看不到任何超出额外的&lt;tr&gt; .

有什么办法可以清除这样的挂标签的 HTML 吗?

【问题讨论】:

    标签: ruby nokogiri mechanize


    【解决方案1】:

    在你的例子中是:

    page.at '/html/body/tr/table'
    

    但也许这样做更有意义:

    page.at 'table'
    

    【讨论】:

    • 问题是我的 xpath 比这更深,我使用 firefox 的 js 代码(忽略额外的 tr)以编程方式获取它。我试图找到一个通用的解决方案,而不是手动解决这种情况的方法。
    • 一般的解决方案是使用正确的 xpath,而不是 firefox 提供的损坏的 xpath。如果您需要示例,请发布链接。
    • 不要使用浏览器来确定节点的路径。浏览器可悲地像小狗一样,几乎可以做任何事情来渲染页面,包括忽略不良标记,并且可能会在 JavaScript 破坏页面移动元素之后向您显示 DOM。从命令行使用nokogiri,或curlwget 下载页面并在编辑器中查看。然后你就会知道实际的标记是什么样子的。
    • 好吧,如果您需要 Nokogiri 像 HTML5 浏览器一样处理 html,您可以切换到 Nokogumbo。使用浏览器很有帮助,但有时您需要使用 Network/Sources 检查器而不是 Elements。
    【解决方案2】:

    使用不那么脆弱的 XPath 查询?

    found = page.at('//table')
    

    【讨论】:

      【解决方案3】:

      您可以使用 Nokogiri 轻松清理它:

      require 'nokogiri'
      
      html = '<html><body><tr><table><tr><td>foo</td></tr></table></tr></body></html>'
      doc = Nokogiri::HTML(html)
      
      inner_table = doc.at('//body/tr/table')
      if (inner_table)
        doc.at('body tr').replace(inner_table)
      end
      
      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><table><tr><td>foo</td></tr></table></body></html>
      

      如果您的 HTML 更复杂,则找到某种类似于 &lt;body&gt;&lt;tr&gt;&lt;table&gt; 节点链的标记,并将其替换为上面的代码。

      请注意,我混合了 XPath 和 CSS 访问器。我更喜欢 CSS 的可读性,但有时 XPath 更容易获得某些东西,或者更能自我记录。

      另外请注意,我将 XPath 和 CSS 与 Nokogiri 的 at 方法一起使用。尽管 Nokogiri 支持 atat_cssat_xpath,但我还是依赖 at,除非我需要明确告诉 Nokogiri 我用作访问器的是 CSS 或 XPath。这是一个方便的事情。这同样适用于 Nokogiri 的 search 方法。

      【讨论】:

        猜你喜欢
        • 2018-09-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-03
        相关资源
        最近更新 更多