using html5lib with xml.etree.ElementTree



我需要的是一种使用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.ElementTreeetree(通常导入为):

返回的不是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...>

相关内容

  • 没有找到相关文章

最新更新