2011-09-05 85 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的答案。