如何从xml中提取所需的数据

时间:2017-04-22 12:07:11

标签: python xml web-scraping

我正在尝试做一些网络报废示例。我从网站下载数据,数据由xml组成,看起来像这样

ValCurs Date="20.04.2016" name="Official exchange rate">
<Valute ID="47">
<NumCode>978</NumCode>
<CharCode>EUR</CharCode>
<Nominal>1</Nominal>
<Name>Euro</Name>
<Value>22.4023</Value>
</Valute>
<Valute ID="44">
<NumCode>840</NumCode>
<CharCode>USD</CharCode>
<Nominal>1</Nominal>
<Name>US Dollar</Name>
<Value>19.7707</Value>
</Valute>
.
.
.
.
.

有超过25种货币。

我想只提取货币名称和代表汇率的价值。我有50天的数据,我想计算这50天每种货币的平均汇率。 我下载数据并保存在xml文件中。我的代码如下。

import os
import requests as rq
from bs4 import BeautifulSoup
from xml.etree import ElementTree as ET


def saveData(path, date):
    session = rq.session()
    url = 'https://www.bnm.md/en/official_exchange_rates?get_xml=1&date=' + date
    datastore = session.get(url)
    with open(path, 'wb') as f:
        f.write(datastore.content)
    value = ET.fromstring('/home/robbin/Desktop/20.04.2016.xml').find('Name/value')
    if value:
        print 'Found value:', value.text

def main():
    dates = ['20.04.2016', '21.04.2016', '22.04.2016']
    paths = []
    for date in dates:
        path = '/home/robbin/Desktop/{}.xml'.format(date)
        paths.append(path)
    for path, date in zip(paths, dates):
        saveData(path, date)


if __name__ == '__main__':
    main() 

我收到了这个错误:   提出错误

xml.etree.ElementTree.ParseError: not well-formed (invalid token): line 1, column 0

我的问题是我无法从此xml数据中提取名称和值数据。我在SO和互联网上看到了一些例子,但它们与我的情况完全不同。如果有人可以提供帮助,那就太好了。

2 个答案:

答案 0 :(得分:0)

如果你在这里正确处理了xml,问题是xml没有正确格式化。第一行和第0列是问题所在。应该有一个开头标记&#34;&lt;&#34;在开始。

答案 1 :(得分:0)

fromstring(...)解析给定的字符串。所以它解析路径而不是xml内容。

应该是:

value = ET.fromstring(datastore.content).find('Name/value')

工作示例:

def saveData(path, date):
    session = rq.session()
    url = 'https://www.bnm.md/en/official_exchange_rates?get_xml=1&date=' + date
    datastore = session.get(url)
    with open(path, 'wb') as f:
        f.write(datastore.content)
    data = ET.fromstring(datastore.content)

    for element in data.iter():
        if element.tag in ('Name', 'Value'):
            print("%s - %s" % (element.tag, element.text))