2016-11-02 81 views
1

我在做類項目,我必須保存鏈接到文本文件的列表。使用python和ElementTree解析XML

我給了XML,並試圖遍歷所有url的,但我很麻煩。

我已經嘗試使用元素樹,但無法遍歷我讀了許多其他問題,並試圖沒有成功。請幫助

的結構是這樣

<urlset xmlns="http://www.crawlingcourse.com/sitemap/1.3"> 
    <url> 
    <loc> 
     http://www.crawlingcourse.com/item-3911512 
    </loc> 
    </url> 
<url>.... 
+1

你的代碼到目前爲止是什麼樣的?它以什麼方式不起作用? – larsks

+0

從示例中,只是想確保您的XML是正確的(所有元素關閉,文檔類型等)? – Eugene

回答

4

我建議你使用lxml高效地解析XML文件。

from lxml import etree 

沒有很好地形成你的XML樣本,我固定它是這樣的:

content = """\ 
<urlset xmlns="http://www.crawlingcourse.com/sitemap/1.3"> 
    <url> 
    <loc> 
     http://www.crawlingcourse.com/item-3911512 
    </loc> 
    </url> 
</urlset>""" 

解析文件,你可以使用etree.parse()。但由於這個樣本是一個字符串,我用etree.XML()

tree = etree.XML(content) 

自然的方式對搜索元素在XML樹使用XPath。舉例來說,你可以這樣做:

loc_list = tree.xpath("//url/loc") 

但你會得到什麼:

for loc in loc_list: 
    print(loc.text) 
# None 

的原因,很可能是你的問題,是<urlset>使用默認命名空間:「http://www.crawlingcourse.com/sitemap/1.3」 。

要使其工作,您需要使用xpath()函數與此命名空間。讓我們給一個名字到這個命名空間:「S」:

NS = {'s': "http://www.crawlingcourse.com/sitemap/1.3"} 

然後,使用s前綴的XPath表達式是這樣的:

loc_list = tree.xpath("//s:url/s:loc", namespaces=NS) 

for loc in loc_list: 
    print(loc.text) 
#  http://www.crawlingcourse.com/item-3911512 

因爲你的XML縮進,你需要剝去空格:

for loc in loc_list: 
    url = loc.text.strip() 
    print(url) 
# http://www.crawlingcourse.com/item-3911512 
+0

謝謝@Laurent花時間解釋。你解決了我的問題,並教我如何實際工作。謝謝你 – hahu

1

嗯,這個問題真的是命名空間。

這裏的工作代碼:

from xml.etree.cElementTree import XML, fromstring, tostring, ElementTree 
xml_string = '<?xml version="1.0"?><urlset><url><loc>http://www.crawlingcourse.com/item-3911512</loc></url></urlset>' 
tree = ElementTree(fromstring(xml_string)) 
print [elem.text for elem in tree.iter(tag='loc')] 

現在,如果你想添加<urlset xmlns="http://www.crawlingcourse.com/sitemap/1.3">,標籤將是不同的。從http://www.w3schools.com/xml/xml_namespaces.asp

XML Namespaces - xmlns屬性。在XML中使用前綴時,必須定義前綴的名稱空間 。命名空間可以通過元素的開始標記中的xmlns屬性來定義 。命名空間 聲明具有以下語法。的xmlns:前綴= 「URI」。

也把我也扔了!