使用Python清理HTML

19

我正在从几个外部来源聚合内容,并发现其中一些内容在其HTML/DOM中包含错误。一个很好的例子是HTML缺少闭合标签或格式不正确的标签属性。是否有一种方法可以在Python中本地清理这些错误,或者我可以安装任何第三方模块来处理这些错误?


这些答案中有没有符合您要求的?如果您需要更多信息,我们一定可以帮忙。 - JudoWill
@JudoWill:是的,我已经成功安装了BeautifulSoup和Tidy。不幸的是,它们没有捕捉到我遇到的很多问题。最终,我自己编写了一个函数来遍历DOM并解决这些问题。感谢你的帮助! - Joel
你能否将自己的函数发布为答案呢?这是我经常遇到的问题,我一直在寻找新的解决方案。 :) - JudoWill
5个回答

20

我建议使用 Beautifulsoup。它有一个出色的解析器,可以优雅地处理格式不正确的标签。一旦你读入整个树形结构,就可以直接输出结果。

from bs4 import BeautifulSoup
tree = BeautifulSoup(bad_html)
good_html = tree.prettify()
我已经多次使用过这个方法,它非常有效。如果您只是从坏的HTML中提取数据,那么BeautifulSoup在提取数据方面确实非常出色。

1
注意性能,BeautifulSoup非常消耗资源。 - Tarantula
1
@Tarantula。我同意,BeautifulSoup的速度相当慢,但它是我见过的唯一能解析那些疯狂畸形的基于HTML的表格的工具。 - JudoWill

11

使用lxml.html.clean.Cleaner模块进行HTML清理的示例。

需要安装lxml模块 — pip install lxml(它是一个用C编写的本地模块,因此可能比纯Python解决方案更快)。

import sys

from lxml.html.clean import Cleaner


def sanitize(dirty_html):
    cleaner = Cleaner(page_structure=True,
                  meta=True,
                  embedded=True,
                  links=True,
                  style=True,
                  processing_instructions=True,
                  inline_style=True,
                  scripts=True,
                  javascript=True,
                  comments=True,
                  frames=True,
                  forms=True,
                  annoying_tags=True,
                  remove_unknown_tags=True,
                  safe_attrs_only=True,
                  safe_attrs=frozenset(['src','color', 'href', 'title', 'class', 'name', 'id']),
                  remove_tags=('span', 'font', 'div')
                  )

    return cleaner.clean_html(dirty_html)


if __name__ == '__main__':

    with open(sys.argv[1]) as fin:

        print(sanitize(fin.read()))

查看文档,了解可以传递给清理程序的所有选项。


如何从具有特定“id”或“class”的代码标签(div)中完全清除它们,包括文本? - Lexx Luxx
@triwo:这不是OOTB支持的,但是你可以使用lxml解析标记并通过类或ID删除节点;例如,请参见https://dev59.com/umsy5IYBdhLWcg3w6yUN。 - ccpizza

4

HTML Tidy Library Project的Python绑定,但自动清理损坏的HTML是一个难题。这与尝试自动修复源代码并没有太大差异 - 可能性太多了。您仍然需要检查输出,并几乎肯定需要手动进行进一步修复。


3

我正在使用lxml将HTML转换为正确的(格式良好的)XML:

from lxml import etree
tree   = etree.HTML(input_text.replace('\r', ''))
output_text = '\n'.join([ etree.tostring(stree, pretty_print=True, method="xml") 
                          for stree in tree ])

...并且在中间进行大量的“危险元素”删除...

(该句内容较为模糊,请提供更多上下文以获得更准确的翻译)

1
可以使用tidylib模块中的tidy_document函数来完成这个操作。
import tidylib
html = '<html>...</html>'
inputEncoding = 'utf8'
options = {
    str("output-xhtml"): True, #"output-xml" : True
    str("quiet"): True,
    str("show-errors"): 0,
    str("force-output"): True,
    str("numeric-entities"): True,
    str("show-warnings"): False,
    str("input-encoding"): inputEncoding,
    str("output-encoding"): "utf8",
    str("indent"): False,
    str("tidy-mark"): False,
    str("wrap"): 0
    };
document, errors = tidylib.tidy_document(html, options=options)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接