运用Python+ElementTree解析XML

7 篇文章 4 订阅
1 篇文章 0 订阅

近日遇到一些XML数据,想把其解析出来,便于后期归纳汇总数据。搜集资料,发现运用Python的ElementTree可以解析XML数据。 XML是一种固有的分层数据格式,表示它的最自然的方式是使用树,XML中结点结构一般形式为:

    <tag attrib="attrib">text</tag>

下面以解析https://data.un.org/ws/rest/conceptscheme/为例展开介绍。
在这里插入图片描述

1.导入包

# -*- coding: utf-8 -*-
from urllib.request import urlopen   ##urllib.request.urlopen()函数用于实现对目标url的访问。
import xml.etree.ElementTree as ET   ##xml.etree.ElementTree用于解析遍历XML文件。
import pandas as pd   ##pandas用于数据记录和保存

2.解析XML

ElementTree提供了parse()、from_string()、ElementTree类ElementTree()等方式解析xml,具体可以参考博客 ,此处采用from_string()。

 # urlopen访问网页
u = urlopen('https://data.un.org/ws/rest/conceptscheme/')
#获取文本
s = u.read().decode('utf-8')
#调用from_string(),返回解析树的根元素
root = ET.fromstring(s)
print(root.tag, ":", root.attrib)  # 打印根元素的tag和属性

3.遍历

可以直接循环遍历,也可以采用find(match)、findall(match) 、 iter(tag=None)等方法来匹配遍历。

# 遍历xml文档的第二层
for elem in root:
    print("第二层节点")
    print ("elem.tag:",elem.tag)
    print ("elem.attrib:",elem.attrib)
    print ("elem.text:",elem.text)
    for i in elem:
        print ("第三层节点")
        print ("elem.tag:",i.tag)
        print ("elem.attrib:",i.attrib)
        print ("elem.text:",i.text)

从打印结果可以看到文件中使用了命名空间,所以在使用tag匹配时要注意加上命名空间。
在这里插入图片描述
在这里插入图片描述
利用上面的遍历方法从xml文件中提取需要的字段。
在这里插入图片描述

##用列表记录字段
ConceptScheme_id=[]
ConceptScheme_agencyID=[]
ConceptId=[]
ConceptName=[]
ConceptDescription=[]

for item in root.iter('{http://www.sdmx.org/resources/sdmxml/schemas/v2_1/structure}ConceptScheme'):
    #获取ConceptScheme
    print("#######")
    #print(item.tag)
    print(item.get("id"),'\t',item.get("agencyID"))
    ##获取每个ConceptScheme中包含的字段Concept
    num=0
    for concept in item.iter("{http://www.sdmx.org/resources/sdmxml/schemas/v2_1/structure}Concept"):
        #print (concept.get("id"))
        #print (concept.tag,concept.attrib,concept.text)
        ConceptScheme_id.append(item.get("id"))
        ConceptScheme_agencyID.append(item.get("agencyID"))
        ConceptId.append(concept.get("id"))
        temp=[]
        for info in concept:
            #print ("concept的name 和 description")
            temp.append(info.text)
            #print (info.text)
        #print(len(temp))
        if len(temp)==1:
            ConceptName.append(temp[0])
            ConceptDescription.append("")
        else:
            ConceptName.append(temp[0])
            ConceptDescription.append(temp[1])

4.数据保存

result=pd.DataFrame()

result['ConceptScheme_id']=ConceptScheme_id
result['ConceptScheme_agencyID']=ConceptScheme_agencyID
result['ConceptId']=ConceptId
result['ConceptName']=ConceptName
result['ConceptDescription']=ConceptDescription
result.to_csv('data/UNSD_Concept.csv')

在这里插入图片描述
完整代码

# -*- coding: utf-8 -*-
from urllib.request import urlopen
import xml.etree.ElementTree as ET
import pandas as pd

# urlopen访问网页
u = urlopen('https://data.un.org/ws/rest/conceptscheme/')
#获取文本
s = u.read().decode('utf-8')

#调用from_string(),返回解析树的根元素
root = ET.fromstring(s)
print(root.tag, ":", root.attrib)  # 打印根元素的tag和属性

#从根节点迭代子节点
for elem in root:
    print("第二层节点")
    print ("elem.tag:",elem.tag)
    print ("elem.attrib:",elem.attrib)
    print ("elem.text:",elem.text)
    for i in elem:
        print ("第三层节点")
        print ("elem.tag:",i.tag)
        print ("elem.attrib:",i.attrib)
        print ("elem.text:",i.text)
 ##用列表记录字段       
ConceptScheme_id=[]
ConceptScheme_agencyID=[]
ConceptId=[]
ConceptName=[]
ConceptDescription=[]

for item in root.iter('{http://www.sdmx.org/resources/sdmxml/schemas/v2_1/structure}ConceptScheme'):
    #获取ConceptScheme
    print("#######")
    #print(item.tag)
    print(item.get("id"),'\t',item.get("agencyID"))
    ##获取每个ConceptScheme中包含的字段Concept
    num=0
    for concept in item.iter("{http://www.sdmx.org/resources/sdmxml/schemas/v2_1/structure}Concept"):
        #print (concept.get("id"))
        #print (concept.tag,concept.attrib,concept.text)
        ConceptScheme_id.append(item.get("id"))
        ConceptScheme_agencyID.append(item.get("agencyID"))
        ConceptId.append(concept.get("id"))
        temp=[]
        for info in concept:
            #print ("concept的name 和 description")
            temp.append(info.text)
            #print (info.text)
        #print(len(temp))
        if len(temp)==1:
            ConceptName.append(temp[0])
            ConceptDescription.append("")
        else:
            ConceptName.append(temp[0])
            ConceptDescription.append(temp[1])
##数据保存                  
result=pd.DataFrame()

result['ConceptScheme_id']=ConceptScheme_id
result['ConceptScheme_agencyID']=ConceptScheme_agencyID
result['ConceptId']=ConceptId
result['ConceptName']=ConceptName
result['ConceptDescription']=ConceptDescription
result.to_csv('data/UNSD_Concept.csv')

ps:初衷是通过撰写博文记录自己所学所用,实现知识的梳理与积累;将其分享,希望能够帮到面临同样困惑的小伙伴儿。如发现博文中存在问题,欢迎随时交流~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值