Python - 使用Tidy解析HTML

1 投票
2 回答
3270 浏览
提问于 2025-04-16 05:32

这段代码处理了一些糟糕的HTML代码,使用Tidy库来清理这些代码,然后把清理后的内容传递给HtmlLib.Reader()。

import tidy
options = dict(output_xhtml=1, 
                add_xml_decl=1, 
                indent=1, 
                tidy_mark=0)

from xml.dom.ext.reader import HtmlLib
reader = HtmlLib.Reader()

doc = reader.fromString(tidy.parseString("<Html>Bad Html.", **options))

看起来我传给fromString的类型不对,这里有个错误追踪信息:

Traceback (most recent call last):
  File "getComicEmbed.py", line 33, in <module>
    doc = reader.fromString(tidy.parseString("<Html>Bad Html.</b>", **options))
  File "C:\Python26\lib\site-packages\_xmlplus\dom\ext\reader\HtmlLib.py", line 67, in fromString
stream = reader.StrStream(str)
  File "C:\Python26\lib\site-packages\_xmlplus\dom\ext\reader\__init__.py", line 24, in StrStream
return cStringIO.StringIO(st)
TypeError: expected read buffer, _Document found

我应该怎么做才好呢?谢谢!

2 个回答

1

我没有用过Python的tidy模块,不太清楚怎么找到它,但看起来你需要在tidy.fromString的结果上调用类似toString的东西,才能把解析后的文档转换回XHTML格式。

如果你想换个方法,可以考虑使用lxml.html。这个库在处理有问题的标记语言方面表现不错,而且提供了一个很棒的ElementTree API,方便你操作结果。它还可以把*ML格式的内容美化打印出来,所以在某种程度上它比tidy更强大,虽然在处理混乱的标记时可能没有那么灵活。

另外,lxml是用C语言写的(其实就像Python的tidy模块一样,它只是封装了一个C库),所以在处理XML时,它的速度比其他一些Python模块快很多。

4

tidy的 parseString 函数会返回一个 _Document 实例,这个实例实现了 __str__ 方法,但没有实现缓冲区接口。因此,HtmlLib.Reader().fromString 不能从中创建一个 StringIO 对象。

这个问题应该比较简单,只需要把:

doc = reader.fromString(tidy.parseString("<Html>Bad Html.", **options))

改成

doc = reader.fromString(str(tidy.parseString("<Html>Bad Html.", **options)))

撰写回答