проблема с деревом элементов, не возвращающим правильные значения при разборе xml - PullRequest
0 голосов
/ 05 апреля 2020

у меня следующая программа. при синтаксическом анализе файла xml с et, у которого более 2 дочерних элементов, когда я нахожусь внутри первого дочернего элемента, собирающего данные, он работает, как предполагалось, но когда я нахожусь внутри второго, он получает данные первого. но когда у xml есть только 1 дочерний элемент, он работает как положено.

это файл xml, который я анализирую только с 1 дочерним элементом

<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

1 Ответ

0 голосов
/ 05 апреля 2020
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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...