我有一个简单的函数来从站点检索XML,并将其存储在字符串中:
def market(typeid):
ping = urllib2.urlopen('http://api.eve-central.com/api/marketstat?usesystem=30000142&typeid=' + str(typeid))
info = ping.read()
return info
然后我使用ElementTree库来解析XML,但这不起作用,没有完全错误,但似乎它认为XML代码只有几行并停在那里,而还有更多元素。我正在寻找远远低于前几个元素的元素,它在第一对元素之后停止,认为它已到达文档的末尾或其他什么?经过一段时间的网络搜索后,我无法弄明白,没有任何帮助。在我的shell中打印出来的XML如下:
<?xml version='1.0' encoding='utf-8'?>
<evec_api version="2.0" method="marketstat_xml">
<marketstat><type id="34">
<buy><volume>14082197693</volume><avg>5.61</avg><max>5.89</max><min>4.61</min><stddev>0.46</stddev><median>5.57</median><percentile>5.87</percentile></buy>
<sell><volume>19614612791</volume><avg>6.31</avg><max>10.00</max><min>5.90</min><stddev>0.64</stddev><median>6.15</median><percentile>6.00</percentile></sell>
<all><volume>34096810484</volume><avg>5.95</avg><max>10.00</max><min>0.50</min><stddev>0.84</stddev><median>6.03</median><percentile>4.26</percentile></all>
</type></marketstat>
</evec_api>
开始解析我正在使用
root = ET.fromstring(data)
并已将ElementTree导入为ET。从我读到的,这是注入&#39;的唯一方法。 XML作为字符串而不是文件。我想如果有一种简单的方法可以将文件下载到临时位置,并使用文件版本,那么也可以使用,但是我对这个文件处于死胡同。
运行print ET.tostring(root)
后,我得到:
<evec_api method="marketstat_xml" version="2.0">
<marketstat><type id="34">
<buy><volume>19627488095</volume><avg>5.69</avg><max>5.91</max> <min>4.61</min><stddev>0.44</stddev><median>5.81</median><percentile>5.90</percentile></buy>
<sell><volume>18831805139</volume><avg>6.32</avg><max>10.00</max><min>6.00</min><stddev>0.66</stddev><median>6.15</median><percentile>6.01</percentile></sell>
<all><volume>38859293234</volume><avg>5.94</avg><max>10.00</max><min>0.50</min><stddev>0.85</stddev><median>5.91</median><percentile>4.26</percentile></all>
</type></marketstat>
</evec_api>
答案 0 :(得分:0)
需要有关您如何尝试的更多详细信息,但这里是迭代DOM树的示例:
In [339]: %cpaste
Pasting code; enter '--' alone on the line to stop or use Ctrl-D.
:x = """
:<evec_api version="2.0" method="marketstat_xml">
: <marketstat><type id="34">
: <buy><volume>14082197693</volume><avg>5.61</avg><max>5.89</max><min>4.61</min><stddev>0.46</stddev><median>5.57</median><percentile>5.87</percentile></buy>
: <sell><volume>19614612791</volume><avg>6.31</avg><max>10.00</max><min>5.90</min><stddev>0.64</stddev><median>6.15</median><percentile>6.00</percentile></sell>
: <all><volume>34096810484</volume><avg>5.95</avg><max>10.00</max><min>0.50</min><stddev>0.84</stddev><median>6.03</median><percentile>4.26</percentile></all>
: </type></marketstat>
:</evec_api>"""
:<EOF>
In [340]: root = ET.fromstring(x)
In [342]: [(xx.text,xx.tag) for xx in root.iter()]
Out[342]: [('\n ', 'evec_api'), (None, 'marketstat'), ('\n ', 'type'), (None, 'buy'), ('14082197693', 'volume'), ('5.61', 'avg'), ('5.89', 'max'), ('4.61', 'min'), ('0.46', 'stddev'), ('5.57', 'median'), ('5.87', 'percentile'), (None, 'sell'), ('19614612791', 'volume'), ('6.31', 'avg'), ('10.00', 'max'), ('5.90', 'min'), ('0.64', 'stddev'), ('6.15', 'median'), ('6.00', 'percentile'), (None, 'all'), ('34096810484', 'volume'), ('5.95', 'avg'), ('10.00', 'max'), ('0.50', 'min'), ('0.84', 'stddev'), ('6.03', 'median'), ('4.26', 'percentile')]
答案 1 :(得分:0)
@salparadise我现在正在工作,并在一定程度上了解它是如何工作的。代码是:
root = ET.fromstring(data)
for buy in root.iter('buy'):
av = buy.find('avg').text
avg = float(av)
print avg
像魅力一样工作。谢谢你!我相信这个教程令人困惑的是它假设root只有1个子集,所以它给出了一切错觉,可以从root的子节点解析,但是在我的XML中,root只有1个直接子项,这对数据来说相当无用,但是,子项将所有数据保存在它下面的子级别中。因此root.iter函数。