我需要的是一种使用html5lib解析器生成真正的xml.etree.ElementTree的方法。(出于可移植性的原因,lxml不是一个选项。)
ELementTree.parse
可以将解析器作为可选参数
xml.etree.ElementTree.parse(source, parser=None)
但目前还不清楚这样的解析器会是什么样子。HTML5中是否有一个类或对象可以用于parser
参数?这两个库关于这个问题的文档都很薄。
上下文:
我有一个格式错误的XHTML文件,无法使用ElementTree.parse
:进行解析
<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Title</title></head>
<body><div class="cls">Note that this br<br>is missing a closing slash</div></body>
</html>
所以我使用了html5lib.parse
和默认的treebuilder="etree"
参数,效果很好。
但html5lib显然不输出xml.etree.ElementTree
对象,只输出一个具有近似相同API的对象。这有两个问题:
- html5lib的
find
不支持namespaces
参数,这使得XPath过于冗长而没有笨拙的包装函数 - Eclipse调试器不支持对html5lib etree进行钻取
所以我不能单独使用ElementTree或html5lib。
给定xml.etree.ElementTree
为etree
(通常导入为):
返回的不是etree.ElementTree
,而是etree.Element
(这与etree.fromstring
返回的内容相同;只有etree.parse
返回etree.ElementTree
)。它确实是etree模块的一部分——它不是类似的API。您遇到的问题适用于etree.fromstring
,就像它适用于html5lib一样。
xml.etree.ElementTree
的Python文档没有提到namespaces
参数——它似乎是ElementTree
对象(但不是Element
对象)的一个未记录的特性。因此,这可能不是真正应该依赖的东西!您最好的选择可能是使用包装器函数。
Eclipse不能通过树的事实是因为当它存在时,html5lib默认为xml.etree.cElementTree
——根据模块的文档,这意味着完全相同,但它是使用CPython的API在C中实现的,从而阻止了Eclipse的调试器运行。您可以使用非加速版本获得一个树生成器(请注意,Python 3.3中的和都是C实现——cElementTree
只是一个不推荐使用的别名),使用以下命令:
import xml.etree.ElementTree as etree
import html5lib
tb = html5lib.getTreeBuilder("etree", implementation=etree)
p = html5lib.HTMLParser(tb)
tree = p.parse("<html>")
您必须将响应封装在ElementTree
中
>>> from xml.etree.ElementTree import ElementTree
>>> from html5lib import parse
>>>
>>> ElementTree(parse("<html>"))
<xml.etree.ElementTree.ElementTree at 0x...>