如何从XML数据中获取特定元素?
我有一些代码用来获取XML数据:
import cStringIO
import pycurl
from xml.etree import ElementTree
_API_KEY = 'my api key'
_ima = '/the/path/to/a/image'
sock = cStringIO.StringIO()
upl = pycurl.Curl()
values = [
("key", _API_KEY),
("image", (upl.FORM_FILE, _ima))]
upl.setopt(upl.URL, "http://api.imgur.com/2/upload.xml")
upl.setopt(upl.HTTPPOST, values)
upl.setopt(upl.WRITEFUNCTION, sock.write)
upl.perform()
upl.close()
xmldata = sock.getvalue()
#print xmldata
sock.close()
得到的数据看起来是这样的:
<?xml version="1.0" encoding="utf-8"?>
<upload><image><name></name><title></title><caption></caption><hash>dxPGi</hash><deletehash>kj2XOt4DC13juUW</deletehash><datetime>2011-06-10 02:59:26</datetime><type>image/png</type><animated>false</animated><width>1024</width><height>768</height><size>172863</size><views>0</views><bandwidth>0</bandwidth></image><links><original>https://i.stack.imgur.com/dxPGi.png</original><imgur_page>http://imgur.com/dxPGi</imgur_page><delete_page>http://imgur.com/delete/kj2XOt4DC13juUW</delete_page><small_square>https://i.stack.imgur.com/dxPGis.jpg</small_square><large_thumbnail>https://i.stack.imgur.com/dxPGil.jpg</large_thumbnail></links></upload>
现在,按照这个回答,我想从数据中提取一些特定的值。
这是我的尝试:
tree = ElementTree.fromstring(xmldata)
url = tree.findtext('original')
webpage = tree.findtext('imgur_page')
delpage = tree.findtext('delete_page')
print 'Url: ' + str(url)
print 'Pagina: ' + str(webpage)
print 'Link de borrado: ' + str(delpage)
如果我尝试添加.text
来获取文本,就会出现AttributeError
错误:
Traceback (most recent call last):
File "<pyshell#28>", line 27, in <module>
url = tree.find('original').text
AttributeError: 'NoneType' object has no attribute 'text'
我在Python的帮助文档中找不到关于ElementTree
这个属性的任何信息。我该如何只获取文本,而不是对象呢?
我找到了一些关于获取文本字符串的信息在这里;但是当我尝试时却出现了TypeError错误:
Traceback (most recent call last):
File "<pyshell#32>", line 34, in <module>
print 'Url: ' + url
TypeError: cannot concatenate 'str' and 'NoneType' objects
如果我尝试打印'Url: ' + str(url)
,就没有错误,但结果显示为None
。
我该如何从这个XML中获取url、网页和delete_page
的数据呢?
1 个回答
2
你的 find()
调用是想要找到树顶层的一个直接子元素,要求这个子元素的标签名是 original
,而不是树下层的任何标签。如果你想找到树中所有标签名为 original
的元素,可以使用:
url = tree.find('.//original').text
ElementTree 的 find()
方法的匹配规则可以在这个页面的表格中找到: http://effbot.org/zone/element-xpath.htm
对于 //
的匹配规则,它说明:
选择当前元素下面所有层级的所有子元素(搜索整个子树)。例如,“.//egg” 会选择整个树中的所有 “egg” 元素。
补充:这里有一些测试代码给你,它使用了你之前发的 XML 示例字符串,我刚刚在 TextMate 中用 XML Tidy 处理过,让它更易读:
from xml.etree import ElementTree
xmldata = '''<?xml version="1.0" encoding="utf-8"?>
<upload>
<image>
<name/>
<title/>
<caption/>
<hash>dxPGi</hash>
<deletehash>kj2XOt4DC13juUW</deletehash>
<datetime>2011-06-10 02:59:26</datetime>
<type>image/png</type>
<animated>false</animated>
<width>1024</width>
<height>768</height>
<size>172863</size>
<views>0</views>
<bandwidth>0</bandwidth>
</image>
<links>
<original>https://i.stack.imgur.com/dxPGi.png</original>
<imgur_page>http://imgur.com/dxPGi</imgur_page>
<delete_page>http://imgur.com/delete/kj2XOt4DC13juUW</delete_page>
<small_square>https://i.stack.imgur.com/dxPGis.jpg</small_square>
<large_thumbnail>https://i.stack.imgur.com/dxPGil.jpg</large_thumbnail>
</links>
</upload>'''
tree = ElementTree.fromstring(xmldata)
print tree.find('.//original').text
在我的机器上(OS X,运行 python 2.6.1),输出结果是:
Ian-Cs-MacBook-Pro:tmp ian$ python test.py
https://i.stack.imgur.com/dxPGi.png