Python XML 解析失败

Python XML parsing failure

我有一个简单的函数可以从站点检索 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 导入。根据我的阅读,这是将 'inject' 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>

需要有关您如何尝试的更多详细信息,但这里有一个遍历 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')]

@salparadise 我现在可以使用它并且在一定程度上了解它是如何工作的。代码是:

root = ET.fromstring(data)
for buy in root.iter('buy'):
  av = buy.find('avg').text
avg = float(av)
print avg

很有魅力。谢谢负载!我认为该教程令人困惑的是,它假设根只有 1 个 child 设置,所以它给人一种错觉,一切都可以从根的 children 中解析,但是在我的XML,根只有1个直接的child,这对数据来说是相当无用的,那个child,但是,保存了它下面sub-level中的所有数据。因此 root.iter 函数。