2011-09-05 52 views
2

我正在用python + lxml处理一些HTML文件。其中一些已经使用MS Word编辑过,我们有<p>标签,例如<o:p>&nbsp</o:p>。 IE和Firefox不会将这些MS标记解释为真正的<p>标记,并且不会在<o:p>标记之前和之后显示换行符,这就是原始编辑者对文件进行格式化的方式。 nbsp的周围没有空格。Python + lxml:如何找到标签的名称空间?

lxml另一方面是整洁的,并且在处理HTML文件后,我们看到所有的<o:p>标签已被更改为正确的<p>标签。不幸的是,在整理完这两个浏览器后,现在显示所有nbsp的换行符,这打破了原始格式。

因此,我的想法是浏览所有这些<o:p>标签,并删除它们或将它们的.text属性添加到父.text属性中,即删除<o:p>标签标记。

from lxml import etree 
import lxml.html 
from StringIO import StringIO 

s='<p>somepara</p> <o:p>msoffice_para</o:p>' 

parser = lxml.html.HTMLParser() 
html=lxml.html.parse(StringIO(s), parser) 

for t in html.xpath("//p"): 
    print "tag: " + t.tag + ", text: '" + t.text + "'" 

结果是:

tag: p, text: 'somepara' 
tag: p, text: 'msoffice_para' 

所以,lxlm去除标签标记的命名空间名称。有没有办法知道哪个<p>标签来自哪个命名空间,所以我只删除那些与<o:p>

谢谢。

回答

1

来自HTML规范:“The HTML syntax does not support namespace declarations”。 所以我认为lxml.html.HTMLParser删除/忽略名称空间。

但是,BeautifulSoup分析HTML的方式不同,所以我认为它可能值得一试。如果你还安装了BeautifulSoup,您可以使用BeautifulSoup解析器与LXML这样的:

import lxml.html.soupparser as soupparser 
import lxml.html 
import io 
s='<p>somepara</p> <o:p>msoffice_para</o:p>' 
html=soupparser.parse(io.BytesIO(s)) 

BeautifulSoup不会删除该命名空间,但它也不承认的命名空间本身。相反,它只是标签名称的一部分。

也就是说,

html.xpath('//o:p',namespaces={'o':'foo'}) 

不起作用。但是,这种解决方法/破解

for t in html.xpath('//*[name()="o:p"]'):  
    print "tag: " + t.tag + ", text: '" + t.text + "'" 

产生

tag: o:p, text: 'msoffice_para' 
0

如果实际上是良好形成的HTML,你可以使用etree.XMLParser代替。否则,请尝试unutbu的答案。

相关问题