2016-11-02 176 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”。

也把我也扔了!