【问题标题】:Repairing invalid HTML with Nokogiri (removing invalid tags)使用 Nokogiri 修复无效 HTML(删除无效标签)
【发布时间】:2012-07-18 10:35:09
【问题描述】:

我正在尝试使用tidy-ext gem 整理一些检索到的 HTML。但是,当 HTML 完全损坏时它会失败,所以我首先尝试使用 Nokogiri 修复 HTML:

repaired_html = Nokogiri::HTML.parse(a.raw_html).to_html

这似乎做得很好,但最近我遇到了一个示例,其中人们将 FBML 标记插入到 HTML 文档中,例如 <fb:like>,尽管无效,但 Nokogiri 以某种方式保留了该标记。 Tidy 然后说Error: <fb:like> is not recognized! 这是可以理解的。

我想知道是否还有其他选项,例如 strict 或强制 Nokogiri 仅包含有效的 HTML 标记而忽略其他所有内容的选项?

【问题讨论】:

    标签: html ruby html-parsing nokogiri


    【解决方案1】:

    您可以使用 Nokogiri 的 XML 解析器来解析 HTML,默认情况下它是严格的,但只提供一点帮助,因为它仍然会进行修正,因此 HTML/XML 稍微正确。通过调整可以传递给解析器的标志,您可以使 Nokogiri 更加严格,因此它将拒绝返回无效文档。 Nokogiri 不是消毒剂或所需标签的白名单。查看 LoofahSanitize 了解该功能。

    如果您的 HTML 内容位于名为 html 的变量中,并且您这样做:

    doc = Nokogiri::XML.parse(html)
    

    然后检查doc.errors,看看你是否有错误。 Nokogiri 将尝试修复它们,但任何产生错误的东西都会被标记在那里。

    例如:

    Nokogiri::XML('<fb:like></fb:like>').errors
    => [#<Nokogiri::XML::SyntaxError: Namespace prefix fb on like is not defined>]
    

    Nokogiri 将尝试修复 HTML:

    Nokogiri::XML('<fb:like></fb:like>').to_xml
    => "<?xml version=\"1.0\"?>\n<like/>\n"
    

    但它只是将其纠正到删除标记上的未知命名空间的地步。

    如果你想剥离这些节点:

    doc = Nokogiri::XML('<fb:like></fb:like>')
    doc.search('like').each{ |n| n.remove }
    doc.to_xml => "<?xml version=\"1.0\"?>\n"
    

    【讨论】:

    • 我试过了,但没有成功。我想不同的解析模型不是解决方案,因为 XML 允许更多的标签(基本上任何想到的......)并且在过滤掉不允许的东西时不会更严格。 - 错误是一个有趣的来源,但告诉我 Entity 'nbsp' not defined 我认为这很奇怪......
    • 相关:(如何在这些 cmets 中添加换行符?!)解析 HTML(就像我在上面发布的那样)会产生错误 Tag fb:like invalid,这是一件好事,因为 Nokogiri 似乎明白有有事吗。但是如何告诉它修复它呢?
    • Nokogiri 不会“修复它”。它为您提供了修复它的工具。告诉它像我的答案中的最后一个示例一样查找并删除标签。无论您是以 XML 模式还是 HTML 模式解析内容,它都有效。如果您想以 HTML 格式查看文档,请使用 doc.to_html
    • 嗯,它似乎确实“稍微”修复了它。正如您所写,它将删除无效前缀fb,从而创建另一个无效标签like,并将其保留在文档中。对我来说这是错误。它要么修复文档以尝试使其有效(即再次解析生成的文档不应产生错误),要么根本不应该改变它。在我看来,似乎发生的是排序或废话修复。我应该如何清除所有无效标签?迭代错误、扫描字符串错误消息并手动删除节点?
    • 修复不良标记不是 Nokogiri 的工作。许多解析器会简单地拒绝解析,而您将无所事事。为了友好和有用,他们选择让 Nokogiri 让您选择使用某些东西,尽管它有点正确或一无所获。它无法决定什么是已清理的文档,只有您可以,因此它可以为您提供一些起点,然后您就可以从那里开始。这没什么大不了的,如果你不知道怎么做,几颗宝石会为你做的。 tidy gem 不是解析器,它所基于的代码显示了它的年龄。
    猜你喜欢
    • 1970-01-01
    • 2013-05-10
    • 2016-07-22
    • 2018-07-09
    • 1970-01-01
    • 1970-01-01
    • 2016-01-08
    • 2022-01-04
    • 2022-01-05
    相关资源
    最近更新 更多