【问题标题】:issue with element tree not returning the correct values when parsing an xml解析 xml 时元素树未返回正确值的问题
【发布时间】:2020-04-07 15:59:39
【问题描述】:

我的程序如下。 当用 et 解析一个超过 2 个子节点的 xml 文件时,当我在第一个子节点中收集数据时,它会按预期工作,但是当我在第二个子节点中时,它会获取第一个子节点的数据。但是当 xml 只有 1 个孩子时,它会按预期工作。

这是我正在解析的只有 1 个孩子的 xml 文件

<exec_api version="2.0" method="marketstat_xml">
 <marketstat>
  <type id="215">
   <buy>
    <volume>161730411</volume>
    <avg>1.91</avg>
    <stddev>2.09</stddev>
    <median>1.75</median>
    <percentile>2.86</percentile>
    <max>10.00</max>
    <min>1.00</min>
   </buy>
   <sell>
    <volume>62024574</volume>
    <avg>7.88</avg>
    <stddev>4.72</stddev>
    <median>6.90</median>
    <percentile>4.72</percentile>
    <max>29.00</max>
    <min>1.40</min>
   </sell>
  </type>
 </marketstat>
</exec_api>

这是我正在使用 atm 的代码

import urllib.request
from urllib.request import Request, urlopen
import xml.etree.ElementTree as ET
from decimal import Decimal


reqs = Request('https://api.evemarketer.com/ec/marketstat?typeid=215', headers={'User-Agent': 'Mozilla/5.0'})


with urllib.request.urlopen(reqs) as url1:
    tree = ET.parse(url1)
    root = tree.getroot()


for type_ in root.iter('type'):
    print(type_.attrib)

    for action in root.find('./marketstat/type'):
        print("  %s" % action.tag)

        if action.tag == 'buy':

            for buy in root.find("./marketstat/type/buy"):
                print("    %s:%.2f" % (  buy.tag   ,    Decimal(  buy.text.replace(',','.')  )  ))

        if action.tag == 'sell':

            for sell in root.find("./marketstat/type/sell"):
                print("    %s:%.2f" % (  sell.tag   ,    Decimal(  sell.text.replace(',','.')  )  ))

这是程序的输出

{'id': '215'}
  buy
    volume:161730411.00
    avg:1.91
    stddev:2.09
    median:1.75
    percentile:2.86
    max:10.00
    min:1.00
  sell
    volume:62024574.00
    avg:7.88
    stddev:4.72
    median:6.90
    percentile:4.72
    max:29.00
    min:1.40

程序正在做的是搜索类型标签,然后买卖,并返回标签和值,然后当我使用这个 xml 时

reqs = Request('https://api.evemarketer.com/ec/marketstat?typeid=215,216', headers={'User-Agent': 'Mozilla/5.0'}) 这是使用新 xml 运行程序所需的唯一更改

<exec_api version="2.0" method="marketstat_xml">
 <marketstat>
  <type id="215">
   <buy>
    <volume>161730411</volume>
    <avg>1.91</avg>
    <stddev>2.09</stddev>
    <median>1.75</median>
    <percentile>2.86</percentile>
    <max>10.00</max>
    <min>1.00</min>
   </buy>
   <sell>
    <volume>62024574</volume>
    <avg>7.88</avg>
    <stddev>4.72</stddev>
    <median>6.90</median>
    <percentile>4.72</percentile>
    <max>29.00</max>
    <min>1.40</min>
   </sell>
  </type>
 <type id="216">
   <buy>
    <volume>154135069</volume>
    <avg>1.40</avg>
    <stddev>2.53</stddev>
    <median>1.00</median>
    <percentile>3.27</percentile>
    <max>8.47</max>
    <min>1.00</min>
   </buy>
   <sell>
    <volume>21843272</volume>
    <avg>12.17</avg>
    <stddev>20.15</stddev>
    <median>8.42</median>
    <percentile>4.71</percentile>
    <max>130.00</max>
    <min>0.17</min>
   </sell>
  </type>
 </marketstat>
</exec_api>

这是程序的结果

{'id': '215'}
  buy
    volume:161730411.00
    avg:1.91
    stddev:2.09
    median:1.75
    percentile:2.86
    max:10.00
    min:1.00
  sell
    volume:62024574.00
    avg:7.88
    stddev:4.72
    median:6.90
    percentile:4.72
    max:29.00
    min:1.40
{'id': '216'}
  buy
    volume:161730411.00
    avg:1.91
    stddev:2.09
    median:1.75
    percentile:2.86
    max:10.00
    min:1.00
  sell
    volume:62024574.00
    avg:7.88
    stddev:4.72
    median:6.90
    percentile:4.72
    max:29.00
    min:1.40

如您所见,转移到 的结果,然后当我增加类型 id 元素的数量时,它们都从第一个获取数据。

谢谢,如果您对代码或问题有什么不明白的地方,请告诉我,我会尝试 awnser

【问题讨论】:

    标签: python python-3.x xml


    【解决方案1】:
    import xml.etree.ElementTree as ET
    from decimal import Decimal
    
    xml = '''<exec_api version="2.0" method="marketstat_xml">
     <marketstat>
      <type id="215">
       <buy>
        <volume>161730411</volume>
        <avg>1.91</avg>
        <stddev>2.09</stddev>
        <median>1.75</median>
        <percentile>2.86</percentile>
        <max>10.00</max>
        <min>1.00</min>
       </buy>
       <sell>
        <volume>62024574</volume>
        <avg>7.88</avg>
        <stddev>4.72</stddev>
        <median>6.90</median>
        <percentile>4.72</percentile>
        <max>29.00</max>
        <min>1.40</min>
       </sell>
      </type>
     <type id="216">
       <buy>
        <volume>154135069</volume>
        <avg>1.40</avg>
        <stddev>2.53</stddev>
        <median>1.00</median>
        <percentile>3.27</percentile>
        <max>8.47</max>
        <min>1.00</min>
       </buy>
       <sell>
        <volume>21843272</volume>
        <avg>12.17</avg>
        <stddev>20.15</stddev>
        <median>8.42</median>
        <percentile>4.71</percentile>
        <max>130.00</max>
        <min>0.17</min>
       </sell>
      </type>
     </marketstat>
    </exec_api>'''
    
    root = ET.fromstring(xml)
    for _type in root.findall('./marketstat/type'):
      print('type: {}'.format(_type.attrib.get('id')))
      buy = _type.find('./buy')
      for prop in list(buy):
        print('{} : {}'.format(prop.tag,prop.text))
      sell = _type.find('./sell')
      for prop in list(sell):
        print('{} : {}'.format(prop.tag,prop.text))
      print('')
    

    输出

    type: 215
    volume : 161730411
    avg : 1.91
    stddev : 2.09
    median : 1.75
    percentile : 2.86
    max : 10.00
    min : 1.00
    volume : 62024574
    avg : 7.88
    stddev : 4.72
    median : 6.90
    percentile : 4.72
    max : 29.00
    min : 1.40
    
    type: 216
    volume : 154135069
    avg : 1.40
    stddev : 2.53
    median : 1.00
    percentile : 3.27
    max : 8.47
    min : 1.00
    volume : 21843272
    avg : 12.17
    stddev : 20.15
    median : 8.42
    percentile : 4.71
    max : 130.00
    min : 0.17
    

    【讨论】:

    • 当我尝试运行它不运行的代码时,这是输出{'id': '215'} buy Traceback (most recent call last): File "c:/Users/fjasis/Desktop/xml_data_import.py", line 20, in &lt;module&gt; for buy in action.find("./marketstat/type/buy"): TypeError: 'NoneType' object is not iterable
    • 感谢您的解决方案,您能告诉我修复过程吗?供以后参考和实施,再次感谢
    • 感谢您的解决方案,您能告诉我修复过程吗?供以后参考和实施,再次感谢
    • 当然。我们首先找到所有type 元素。我们知道,对于这样的元素,有 1 个买入元素和 1 个卖出元素。因此,我们循环遍历类型,并为每个类型找到买卖。一旦我们拥有它们 - 我们打印他们的孩子。如果我的回答对您有帮助,请随时投票。
    • 谢谢,我投了赞成票,但由于我是堆栈溢出的新手,它没有在 awnser 上注册,也推销它是一个好的 awnser,再次感谢,如果我需要,我以后可以联系你吗一些python相关的帮助?
    猜你喜欢
    • 1970-01-01
    • 2012-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-09
    • 1970-01-01
    • 2020-09-20
    • 2016-12-17
    相关资源
    最近更新 更多