Python 脚本无法从 XML 中提取数据

标签 python python-3.x xml lxml

我正在尝试通过此 XML 文件解析和获取数据。但我的代码没有按预期工作,而是什么也不显示。这是我正在使用的 XML 文件:

<feed xml:base="http://data.treasury.gov/Feed.svc/">
  <title type="text">DailyTreasuryYieldCurveRateData</title>
  <id>
    http://data.treasury.gov/feed.svc/DailyTreasuryYieldCurveRateData
  </id>
  <updated>2019-11-04T07:15:32Z</updated>
  <link rel="self" title="DailyTreasuryYieldCurveRateData" href="DailyTreasuryYieldCurveRateData"/>
  <entry>
    <id>
      http://data.treasury.gov/Feed.svc/DailyTreasuryYieldCurveRateData(7258)
    </id>
    <title type="text"/>
    <updated>2019-11-04T07:15:32Z</updated>
    <author>
      <name/>
    </author>
    <link rel="edit" title="DailyTreasuryYieldCurveRateDatum" href="DailyTreasuryYieldCurveRateData(7258)"/>
    <category term="TreasuryDataWarehouseModel.DailyTreasuryYieldCurveRateDatum" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
    <content type="application/xml">
      <m:properties>
        <d:Id m:type="Edm.Int32">7258</d:Id>
        <d:NEW_DATE m:type="Edm.DateTime">2019-01-02T00:00:00</d:NEW_DATE>
        <d:BC_1MONTH m:type="Edm.Double">2.4</d:BC_1MONTH>
        <d:BC_2MONTH m:type="Edm.Double">2.4</d:BC_2MONTH>
        <d:BC_3MONTH m:type="Edm.Double">2.42</d:BC_3MONTH>
        <d:BC_6MONTH m:type="Edm.Double">2.51</d:BC_6MONTH>
        <d:BC_1YEAR m:type="Edm.Double">2.6</d:BC_1YEAR>
        <d:BC_2YEAR m:type="Edm.Double">2.5</d:BC_2YEAR>
        <d:BC_3YEAR m:type="Edm.Double">2.47</d:BC_3YEAR>
        <d:BC_5YEAR m:type="Edm.Double">2.49</d:BC_5YEAR>
        <d:BC_7YEAR m:type="Edm.Double">2.56</d:BC_7YEAR>
        <d:BC_10YEAR m:type="Edm.Double">2.66</d:BC_10YEAR>
        <d:BC_20YEAR m:type="Edm.Double">2.83</d:BC_20YEAR>
        <d:BC_30YEAR m:type="Edm.Double">2.97</d:BC_30YEAR>
        <d:BC_30YEARDISPLAY m:type="Edm.Double">2.97</d:BC_30YEARDISPLAY>
      </m:properties>
    </content>
  </entry>
  <entry>
  <id>
    http://data.treasury.gov/Feed.svc/DailyTreasuryYieldCurveRateData(7259)
  </id>
  <title type="text"/>
  <updated>2019-11-04T07:15:32Z</updated>
  <author>
    <name/>
  </author>
  <link rel="edit" title="DailyTreasuryYieldCurveRateDatum" href="DailyTreasuryYieldCurveRateData(7259)"/>
  <category term="TreasuryDataWarehouseModel.DailyTreasuryYieldCurveRateDatum" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
  <content type="application/xml">
    <m:properties>
      <d:Id m:type="Edm.Int32">7259</d:Id>
      <d:NEW_DATE m:type="Edm.DateTime">2019-01-03T00:00:00</d:NEW_DATE>
      <d:BC_1MONTH m:type="Edm.Double">2.42</d:BC_1MONTH>
      <d:BC_2MONTH m:type="Edm.Double">2.42</d:BC_2MONTH>
      <d:BC_3MONTH m:type="Edm.Double">2.41</d:BC_3MONTH>
      <d:BC_6MONTH m:type="Edm.Double">2.47</d:BC_6MONTH>
      <d:BC_1YEAR m:type="Edm.Double">2.5</d:BC_1YEAR>
      <d:BC_2YEAR m:type="Edm.Double">2.39</d:BC_2YEAR>
      <d:BC_3YEAR m:type="Edm.Double">2.35</d:BC_3YEAR>
      <d:BC_5YEAR m:type="Edm.Double">2.37</d:BC_5YEAR>
      <d:BC_7YEAR m:type="Edm.Double">2.44</d:BC_7YEAR>
      <d:BC_10YEAR m:type="Edm.Double">2.56</d:BC_10YEAR>
      <d:BC_20YEAR m:type="Edm.Double">2.75</d:BC_20YEAR>
      <d:BC_30YEAR m:type="Edm.Double">2.92</d:BC_30YEAR>
      <d:BC_30YEARDISPLAY m:type="Edm.Double">2.92</d:BC_30YEARDISPLAY>
    </m:properties>
  </content>
</entry>
<entry>
  <id>
    http://data.treasury.gov/Feed.svc/DailyTreasuryYieldCurveRateData(7260)
  </id>
  <title type="text"/>
  <updated>2019-11-04T07:15:32Z</updated>
  <author>
    <name/>
  </author>
  <link rel="edit" title="DailyTreasuryYieldCurveRateDatum" href="DailyTreasuryYieldCurveRateData(7260)"/>
  <category term="TreasuryDataWarehouseModel.DailyTreasuryYieldCurveRateDatum" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
  <content type="application/xml">
     <m:properties>
       <d:Id m:type="Edm.Int32">7260</d:Id>
       <d:NEW_DATE m:type="Edm.DateTime">2019-01-04T00:00:00</d:NEW_DATE>
       <d:BC_1MONTH m:type="Edm.Double">2.4</d:BC_1MONTH>
       <d:BC_2MONTH m:type="Edm.Double">2.42</d:BC_2MONTH>
       <d:BC_3MONTH m:type="Edm.Double">2.42</d:BC_3MONTH>
       <d:BC_6MONTH m:type="Edm.Double">2.51</d:BC_6MONTH>
       <d:BC_1YEAR m:type="Edm.Double">2.57</d:BC_1YEAR>
       <d:BC_2YEAR m:type="Edm.Double">2.5</d:BC_2YEAR>
       <d:BC_3YEAR m:type="Edm.Double">2.47</d:BC_3YEAR>
       <d:BC_5YEAR m:type="Edm.Double">2.49</d:BC_5YEAR>
       <d:BC_7YEAR m:type="Edm.Double">2.56</d:BC_7YEAR>
       <d:BC_10YEAR m:type="Edm.Double">2.67</d:BC_10YEAR>
       <d:BC_20YEAR m:type="Edm.Double">2.83</d:BC_20YEAR>
       <d:BC_30YEAR m:type="Edm.Double">2.98</d:BC_30YEAR>
       <d:BC_30YEARDISPLAY m:type="Edm.Double">2.98</d:BC_30YEARDISPLAY>
     </m:properties>
   </content>
 </entry>
</feed>

到目前为止我已经尝试过:

import requests as rq
import lxml.etree as ET

tree = ET.parse('DailyTreasuryYieldCurveRateData')
root = tree.getroot()

for ele in root.xpath('./entry/content/m:properties', 
                  namespaces={'m': 'http://schemas.microsoft.com/ado/2007/08/dataservices/scheme'}):
    print(ele)
    for foo in ele:
        print(foo.tag, foo.text)

但是,什么也没有显示。

我希望输出是:

NEW_DATE 2019-10-31T00:00:00
BC_1MONTH 1.59
BC_2MONTH 1.59
BC_3MONTH 1.59
BC_6MONTH 1.57
BC_1YEAR 1.54
BC_2YEAR 1.52
BC_3YEAR 1.52
BC_5YEAR 1.51
BC_7YEAR 1.6
BC_10YEAR 1.69
BC_20YEAR 2
BC_30YEAR 2.17
BC_30YEARDISPLAY 2.17

同样,它应该循环到完整的 XML 并生成类似的输出!请告诉我哪里错了。

最佳答案

您可以使用 python-benedict 轻松完成此操作,这是一个令人惊叹的 dict 子类。

要安装它,只需运行pip install python-benedict,然后:

data_xml = """
<feed xml:base="http://data.treasury.gov/Feed.svc/">
  <title type="text">DailyTreasuryYieldCurveRateData</title>
  <id>
    http://data.treasury.gov/feed.svc/DailyTreasuryYieldCurveRateData
  </id>
  <updated>2019-11-04T07:15:32Z</updated>
  <link rel="self" title="DailyTreasuryYieldCurveRateData" href="DailyTreasuryYieldCurveRateData"/>
  <entry>
    <id>
      http://data.treasury.gov/Feed.svc/DailyTreasuryYieldCurveRateData(7258)
    </id>
    <title type="text"/>
    <updated>2019-11-04T07:15:32Z</updated>
    <author>
      <name/>
    </author>
    <link rel="edit" title="DailyTreasuryYieldCurveRateDatum" href="DailyTreasuryYieldCurveRateData(7258)"/>
    <category term="TreasuryDataWarehouseModel.DailyTreasuryYieldCurveRateDatum" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
    <content type="application/xml">
      <m:properties>
        <d:Id m:type="Edm.Int32">7258</d:Id>
        <d:NEW_DATE m:type="Edm.DateTime">2019-01-02T00:00:00</d:NEW_DATE>
        <d:BC_1MONTH m:type="Edm.Double">2.4</d:BC_1MONTH>
        <d:BC_2MONTH m:type="Edm.Double">2.4</d:BC_2MONTH>
        <d:BC_3MONTH m:type="Edm.Double">2.42</d:BC_3MONTH>
        <d:BC_6MONTH m:type="Edm.Double">2.51</d:BC_6MONTH>
        <d:BC_1YEAR m:type="Edm.Double">2.6</d:BC_1YEAR>
        <d:BC_2YEAR m:type="Edm.Double">2.5</d:BC_2YEAR>
        <d:BC_3YEAR m:type="Edm.Double">2.47</d:BC_3YEAR>
        <d:BC_5YEAR m:type="Edm.Double">2.49</d:BC_5YEAR>
        <d:BC_7YEAR m:type="Edm.Double">2.56</d:BC_7YEAR>
        <d:BC_10YEAR m:type="Edm.Double">2.66</d:BC_10YEAR>
        <d:BC_20YEAR m:type="Edm.Double">2.83</d:BC_20YEAR>
        <d:BC_30YEAR m:type="Edm.Double">2.97</d:BC_30YEAR>
        <d:BC_30YEARDISPLAY m:type="Edm.Double">2.97</d:BC_30YEARDISPLAY>
      </m:properties>
    </content>
  </entry>
  <entry>
  <id>
    http://data.treasury.gov/Feed.svc/DailyTreasuryYieldCurveRateData(7259)
  </id>
  <title type="text"/>
  <updated>2019-11-04T07:15:32Z</updated>
  <author>
    <name/>
  </author>
  <link rel="edit" title="DailyTreasuryYieldCurveRateDatum" href="DailyTreasuryYieldCurveRateData(7259)"/>
  <category term="TreasuryDataWarehouseModel.DailyTreasuryYieldCurveRateDatum" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
  <content type="application/xml">
    <m:properties>
      <d:Id m:type="Edm.Int32">7259</d:Id>
      <d:NEW_DATE m:type="Edm.DateTime">2019-01-03T00:00:00</d:NEW_DATE>
      <d:BC_1MONTH m:type="Edm.Double">2.42</d:BC_1MONTH>
      <d:BC_2MONTH m:type="Edm.Double">2.42</d:BC_2MONTH>
      <d:BC_3MONTH m:type="Edm.Double">2.41</d:BC_3MONTH>
      <d:BC_6MONTH m:type="Edm.Double">2.47</d:BC_6MONTH>
      <d:BC_1YEAR m:type="Edm.Double">2.5</d:BC_1YEAR>
      <d:BC_2YEAR m:type="Edm.Double">2.39</d:BC_2YEAR>
      <d:BC_3YEAR m:type="Edm.Double">2.35</d:BC_3YEAR>
      <d:BC_5YEAR m:type="Edm.Double">2.37</d:BC_5YEAR>
      <d:BC_7YEAR m:type="Edm.Double">2.44</d:BC_7YEAR>
      <d:BC_10YEAR m:type="Edm.Double">2.56</d:BC_10YEAR>
      <d:BC_20YEAR m:type="Edm.Double">2.75</d:BC_20YEAR>
      <d:BC_30YEAR m:type="Edm.Double">2.92</d:BC_30YEAR>
      <d:BC_30YEARDISPLAY m:type="Edm.Double">2.92</d:BC_30YEARDISPLAY>
    </m:properties>
  </content>
</entry>
<entry>
  <id>
    http://data.treasury.gov/Feed.svc/DailyTreasuryYieldCurveRateData(7260)
  </id>
  <title type="text"/>
  <updated>2019-11-04T07:15:32Z</updated>
  <author>
    <name/>
  </author>
  <link rel="edit" title="DailyTreasuryYieldCurveRateDatum" href="DailyTreasuryYieldCurveRateData(7260)"/>
  <category term="TreasuryDataWarehouseModel.DailyTreasuryYieldCurveRateDatum" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
  <content type="application/xml">
     <m:properties>
       <d:Id m:type="Edm.Int32">7260</d:Id>
       <d:NEW_DATE m:type="Edm.DateTime">2019-01-04T00:00:00</d:NEW_DATE>
       <d:BC_1MONTH m:type="Edm.Double">2.4</d:BC_1MONTH>
       <d:BC_2MONTH m:type="Edm.Double">2.42</d:BC_2MONTH>
       <d:BC_3MONTH m:type="Edm.Double">2.42</d:BC_3MONTH>
       <d:BC_6MONTH m:type="Edm.Double">2.51</d:BC_6MONTH>
       <d:BC_1YEAR m:type="Edm.Double">2.57</d:BC_1YEAR>
       <d:BC_2YEAR m:type="Edm.Double">2.5</d:BC_2YEAR>
       <d:BC_3YEAR m:type="Edm.Double">2.47</d:BC_3YEAR>
       <d:BC_5YEAR m:type="Edm.Double">2.49</d:BC_5YEAR>
       <d:BC_7YEAR m:type="Edm.Double">2.56</d:BC_7YEAR>
       <d:BC_10YEAR m:type="Edm.Double">2.67</d:BC_10YEAR>
       <d:BC_20YEAR m:type="Edm.Double">2.83</d:BC_20YEAR>
       <d:BC_30YEAR m:type="Edm.Double">2.98</d:BC_30YEAR>
       <d:BC_30YEARDISPLAY m:type="Edm.Double">2.98</d:BC_30YEARDISPLAY>
     </m:properties>
   </content>
 </entry>
</feed>
"""

现在初始化一个 benedict 实例:

from benedict import benedict as bdict

# this method accepts a data string, a file path or a file url
data = bdict.from_xml(data_xml)
# print(data.dump())

entries = data['feed.entry']
for entry in entries:
    props = bdict(bdict(entry)['content.m:properties'])
    # print(props.dump())
    
    for key, value in props.items():
        print(key, value['#text'])
    print('-----')

python-benedict 经过充分测试、记录并在 GitHub 上开源:

https://github.com/fabiocaccamo/python-benedict

免责声明:我是该项目的作者。

关于Python 脚本无法从 XML 中提取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58692636/

相关文章:

xml - 如何使用 Scala 验证 XML 文件的模式?

Python tqdm 包 - 如何配置状态栏更新频率较低

Python "triplet"字典?

python - 有没有一种从路径中获取 XML 元素的快速方法?

python-3.x - 如何在不使用 Flask 的情况下将 Python 应用程序绑定(bind)到 Heroku 上的端口?

c# - 使用 XPath 的 SelectNodes 忽略节点名称中的大小写

iphone - 如何从 iOS 应用程序发送 POST XML?

python - sqlalchemy: "Neither ' InstrumentedAttribute' 对象或 'Comparator' 对象都有一个属性“错误

python - 如何使用 openpyxl 仅解析工作簿中的特定工作表 - 或者如何忽略空工作表?

python - python3 参数定义中的 docopt