【问题标题】:How do I fix wrongly nested / unclosed HTML tags?如何修复错误嵌套/未闭合的 HTML 标签?
【发布时间】:2008-11-16 04:14:57
【问题描述】:

我需要通过以正确的嵌套顺序关闭任何打开的标签来清理用户提交的 HTML。我一直在寻找一种算法或 Python 代码来执行此操作,但除了 PHP 中的一些半生不熟的实现等之外,没有找到任何东西。

例如,类似

<p>
  <ul>
    <li>Foo

变成

<p>
  <ul>
    <li>Foo</li>
  </ul>
</p>

任何帮助将不胜感激:)

【问题讨论】:

  • 这当然——通常——是一个“坏主意”(TM)。为用户修复标签可能会也可能不会产生他想要的结果。我宁愿验证输入,拒绝更新并尽可能多地告诉用户我认为有什么问题(建议修复,但不自动执行)。除了!你的例子说明了我的观点:&lt;ul&gt; 不允许在 &lt;p&gt; 内,所以你的“修复”实际上什么也没修复。

标签: python html algorithm xhtml


【解决方案1】:

使用 BeautifulSoup:

from BeautifulSoup import BeautifulSoup
html = "<p><ul><li>Foo"
soup = BeautifulSoup(html)
print soup.prettify()

得到你

<p>
 <ul>
  <li>
   Foo
  </li>
 </ul>
</p>

据我所知,您无法控制将

  • 标记放在与 Foo 不同的行上。

    使用整洁:

    import tidy
    html = "<p><ul><li>Foo"
    print tidy.parseString(html, show_body_only=True)
    

    得到你

    <ul>
    <li>Foo</li>
    </ul>
    

    不幸的是,我不知道如何在示例中保留

    标记。 Tidy 将其解释为一个空段落而不是一个未闭合的段落,所以这样做

    print tidy.parseString(html, show_body_only=True, drop_empty_paras=False)
    

    出来

    <p></p>
    <ul>
    <li>Foo</li>
    </ul>
    

    当然,您的示例中的

    标记最终是多余的,因此您可以不用它。

    最后,Tidy 也可以做缩进:

    print tidy.parseString(html, show_body_only=True, indent=True)
    

    变成

    <ul>
      <li>Foo
      </li>
    </ul>
    

    所有这些都有其起伏,但希望其中一个足够接近。

  • 【讨论】:

    • tidy 将其视为空元素的原因是因为 p 元素不允许包含 ul 元素。
    • P 元素只能包含内联元素,如 a、abbr、首字母缩略词、b、bdo、big、br、button、cite、code、del、dfn、em、i、img、input、ins , kbd, label, map, object, q, samp, script select, small, span, strong, sub, sup, textarea, tt and var.
    • 我建议在使用 BeautifulSoup 时安装 lxml,因为这似乎对标记修复有很大帮助(pip install lxml)。 BeautifulSoup 会自动选择 lxml 先进行 html 解析(如果可用)
    【解决方案2】:

    通过Tidy 或其移植的libraries 之一运行它。

    尝试手动编写代码,您想挖出你的眼睛。

    【讨论】:

      【解决方案3】:

      使用 html5lib,效果很好! 像这样。

      soup = BeautifulSoup(data, 'html5lib')

      【讨论】:

      • 你就是那个男人。我一直试图弄清楚为什么我无法解析特定的网站。将'html5lib' 添加到soup(page_html, 'html.parser'') 确实很神奇。 :)
      【解决方案4】:

      刚才,我得到了一个 html,其中 lxml 和 pyquery 不能正常工作,似乎 html 中有一些错误。 由于Tidy在windows中不容易安装,所以我选择BeautifulSoup。 但我发现:

      from BeautifulSoup import BeautifulSoup
      import lxml.html
      soup = BeautifulSoup(page)
      h = lxml.html(soup.prettify())
      

      h = lxml.html(page)一样

      真正解决我问题的是soup = BeautifulSoup(page, 'html5lib')
      您应该先安装html5lib,然后可以将其用作BeautifulSoup 中的解析器。 html5lib parser 似乎比其他的更好。

      希望这可以帮助某人。

      【讨论】:

        【解决方案5】:

        我尝试使用以下方法,但在 python 3

        失败
        from BeautifulSoup import BeautifulSoup
        soup = BeautifulSoup(page, 'html5lib')
        

        我在下面尝试并获得了成功

        soup = bs4.BeautifulSoup(html, 'html5lib')
        f_html = soup.prettify()
        print(f'Formatted html::: {f_html}')
        

        【讨论】:

          猜你喜欢
          • 2012-01-19
          • 1970-01-01
          • 2017-02-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-04-07
          • 2022-01-13
          相关资源
          最近更新 更多