XML页面上的HTML Parser,获取数据字典

时间:2015-04-04 21:12:10

标签: python xml python-3.x xml-parsing

我有一个xml页面,其中包含以下信息:

<currency xmlns:xxsi>
<Observation>
    <Currency_name>U.S. dollar </Currency_name>
    <Observation_ISO4217>USD</Observation_ISO4217>
    <Observation_date>2015-03-09</Observation_date>
    <Observation_data>1.2598</Observation_data>
    <Observation_data_reciprocal>0.7938</Observation_data_reciprocal>
</Observation>
<Observation>
    <Currency_name>U.S. dollar </Currency_name>
    <Observation_ISO4217>USD</Observation_ISO4217>
    <Observation_date>2015-03-11</Observation_date>
    <Observation_data>1.2764</Observation_data>
    <Observation_data_reciprocal>0.7835</Observation_data_reciprocal>
</Observation>
<Observation>
    <Currency_name>Argentine peso</Currency_name>
    <Observation_ISO4217>ARS</Observation_ISO4217>
    <Observation_date>2015-03-09</Observation_date>
    <Observation_data>0.1438</Observation_data>
    <Observation_data_reciprocal>6.9541</Observation_data_reciprocal>
</Observation>
<Observation>
    <Currency_name>Argentine peso</Currency_name>
    <Observation_ISO4217>ARS</Observation_ISO4217>
    <Observation_date>2015-03-10</Observation_date>
    <Observation_data>0.1440</Observation_data>
    <Observation_data_reciprocal>6.9444</Observation_data_reciprocal>
</Observation>
</currency>

我想要一种处理数据的方法,以便我可以从中获取信息,例如,如果我想比较同一种货币的两个日期,或者我想比较两个不同国家的货币。我遇到的问题是尝试将这些信息放入字典中作为存储它的好方法。

我目前使用以下代码,但由于相同国家/地区的多个数据,它无法正常工作。实际页面每个国家/地区共有五(5)个相同的国家/地区(共57个)

class myHTMLParser(HTMLParser):

def __init__(self):
    HTMLParser.__init__(self)
    self.country = []
    self.data = []  
    self.dic = {}
    self.nameFlag = False

def handle_starttag(self, tag, attrs):
    if tag == 'currency_name':
        self.nameFlag = True
    else:
        self.nameFlag = False

def handle_endtag(self, tag):
    pass

def handle_data(self, data):
    if data.strip() != '' and self.nameFlag == True:
        self.dic[data.strip()] = []

有人可以帮我找到一个存储多个国家/地区数据的好方法吗?

2 个答案:

答案 0 :(得分:1)

假设您没有标记语言中的嵌套元素,您可以从这样的简单解析器开始:

from html.parser import HTMLParser

class MyHTMLParser(HTMLParser):
    def __init__(self):
        HTMLParser.__init__(self)
        self.content = []
        self.observation = False
        self.element = None

    def handle_starttag(self, tag, attrs):
        print(tag)
        if tag == 'observation':
            self.content.append({})
            self.observation = True
        elif self.observation:
            self.element = tag
            self.content[-1][self.element] = ""

    def handle_endtag(self, tag):
        if tag == 'observation':
            self.observation = False

        self.element = None

    def handle_data(self, data):
        if self.element:
            self.content[-1][self.element] += data

from pprint import pprint

with open("data.someml", "rt") as infile:
    parser = MyHTMLParser()
    parser.feed(infile.read())

    pprint(parser.content)

根据您的输入文件,这将产生:

[{'currency_name': 'U.S. dollar ',
  'observation_data': '1.2598',
  'observation_data_reciprocal': '0.7938',
  'observation_date': '2015-03-09',
  'observation_iso4217': 'USD'},
 {'currency_name': 'U.S. dollar ',
  'observation_data': '1.2764',
  'observation_data_reciprocal': '0.7835',
  'observation_date': '2015-03-11',
  'observation_iso4217': 'USD'},
 {'currency_name': 'Argentine peso',
  'observation_data': '0.1438',
  'observation_data_reciprocal': '6.9541',
  'observation_date': '2015-03-09',
  'observation_iso4217': 'ARS'},
 {'currency_name': 'Argentine peso',
  'observation_data': '0.1440',
  'observation_data_reciprocal': '6.9444',
  'observation_date': '2015-03-10',
  'observation_iso4217': 'ARS'}]

这里的关键思想是每次遇到observation开始标记时创建一个新记录(作为字典)。根据之前解释的假设,任何其他开始标记都将引入数据字段。

答案 1 :(得分:0)

如果您不关心 如何解析XML,我建议您使用Martin Blechxmltodict模块。

由于您的文件缺少单个文档元素,因此您需要哄骗它与以下内容合作:

import xmltodict

with open('input.txt') as f:
    data = f.read()
    d = xmltodict.parse("<root>" + data + "</root>")

d = d['root']

然后,您可以使用以下内容访问XML结构:

print(d['Observation'][0]['Currency_name'])     # U.S. dollar
print(d['Observation'][0]['Observation_date'])  # 2015-03-09

或者,循环所有观察结果:

for obs in d['Observation']:
    print(obs['Currency_name'])
    print(obs['Observation_date'])
    print(obs['Observation_data'])
    print('---')

输出:

U.S. dollar
2015-03-09
1.2598
---
U.S. dollar
2015-03-11
1.2764
---
Argentine peso
2015-03-09
0.1438
---
Argentine peso
2015-03-10
0.1440
---