我正在使用python + lxml处理一些HTML文件。其中一些已经使用MS Word进行了编辑,例如我们将<p>
标记写为<o:p> </o:p>
。 IE和Firefox不会将这些MS标记解释为真正的<p>
标记,并且不会在<o:p>
标记之前和之后显示换行符,这就是原始编辑者对文件进行格式化的方式,例如周围没有空格。
lxml很整洁,在处理完HTML文件后,我们发现所有<o:p>
标记都已更改为正确的<p>
标记。不幸的是,在整理完两个浏览器之后,现在会在所有的浏览器周围显示换行符,这会打破原始格式。
所以,我的想法是浏览所有这些<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>
的标记?
感谢。
答案 0 :(得分:1)
来自HTML规范:“The HTML syntax does not support namespace declarations”。
所以我认为lxml.html.HTMLParser
删除/忽略命名空间。
然而,BeautifulSoup以不同的方式解析HTML,所以我认为它可能值得一试。如果你还安装了BeautifulSoup,你可以像这样使用带有lxml的BeautifulSoup解析器:
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'
答案 1 :(得分:0)
如果html实际上格式正确,您可以使用etree.XMLParser
代替。否则,试试unutbu的答案。