使用lxml解析HTML时如何保留命名空间信息?

时间:2011-07-06 13:34:16

标签: python html lxml facebook-like xml-namespaces

>>> from lxml.etree import HTML, tostring
>>> tostring(HTML('<fb:like>'))
'<html><body><like/></body></html>'

请注意标记从<fb:like>变为简单<like>

这使得将XFBML与lxml结合使用的处理页面变得更加困难。 (同样的事情发生在<g:plusone></g:plusone>

感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

尝试添加缺少的名称空间前缀定义。 lxml将avoid the namespaces otherwise,据说可以让你更轻松。

您尝试解析的网站很可能不包含这些命名空间定义,因此您应该添加它们。

像这样:xmlns:adlcp="http://xxx/yy/zzz"

答案 1 :(得分:1)

解决此问题的一种方法是patch libxml2

在SAX2.c(https://git.gnome中)中引用libxml2.9.2(https://git.gnome.org/browse/libxml2/tree/?id=v2.9.2)的源代码。 org / browse / libxml2 / tree / SAX2.c?id = v2.9.2)(用于创建DOM树的内部SAX解析器)在第1699行,xmlns属性在HTML模式下不被解析,并且它们被解析为任何行和1740处的其他属性。因此,调整行1622是有意义的,行1622将名称拆分为前缀和本地部分。变化:

name = xmlSplitQName(ctxt, fullname, &prefix);

if (!ctxt->html) {
    name = xmlSplitQName(ctxt, fullname, &prefix);
} else {
    name = xmlStrdup(fullname);
    prefix = NULL;
}

然后libxml2会将<o:p>之类的标签视为名称为o:p的元素,也就是说,冒号包含在元素名称中,没有特殊含义。这是HTML中的正确解释。例如,the HTML5 specification says

  

在HTML语法中,名称空间前缀和名称空间声明与XML中的效果不同。例如,冒号在HTML元素名称中没有特殊含义。

希望此更改将被批准用于未来版本的libxml2。有一个开放的错误报告(https://bugzilla.gnome.org/show_bug.cgi?id=654146)。