Python解析XML转CSV遇KeyError及数据不匹配问题求助
解决XML转CSV时的KeyError及数据不匹配问题
1. 排查KeyError: 'debut'的原因
这个错误说明你的代码在尝试访问一个不存在的字典键debut,大概率是以下两种情况:
- 你混淆了XML里的字段名:目标XML(roulez-eco的每日油价数据)的
<pdv>或<carburant>节点里根本没有debut这个属性/子节点,可能是把maj(更新时间字段)之类的名称写错了。 - 解析逻辑有问题:比如你错误地将某个子节点的文本当成了字典键,或者遍历节点时遗漏了判断,导致访问了空节点的键。
解决步骤:
- 先打印单个解析后的节点数据,比如
print(pdv.attrib)或print(carburant.attrib),确认实际存在的属性名,避免硬编码不存在的键。 - 如果需要时间相关字段,检查XML里的
<maj>属性(属于<carburant>节点),这才是对应油价的更新时间。
2. 解决CSV输出与原XML不匹配的问题
移除出错代码后数据不匹配,通常是解析逻辑没覆盖完整的XML结构,常见问题和修复方案:
核心XML结构明确
目标XML的根节点是<pdvs>,包含多个<pdv>(加油站)节点:
- 每个
<pdv>有基础属性(id、latitude、longitude等),还有<adresse>、<ville>等子节点。 - 每个
<pdv>下有多个<carburant>子节点,对应不同油品的价格信息。
常见错误及修复
- 只提取了加油站基础信息,遗漏油品数据:很多人会把每个加油站输出一行,但实际每个加油站的每种油品都对应一行CSV,需要嵌套遍历
<carburant>节点。 - 字段映射错误:比如把
<carburant>的nom属性写成了type,或者把<pdv>的latitude写成了lat,导致数据错位。 - 未处理空节点:部分加油站可能缺少
<adresse>或某个油品,直接访问会报错或漏数据,需要加判断。
正确的解析代码示例
import xml.etree.ElementTree as ET import csv # 可直接从URL解析,或先下载到本地再解析 tree = ET.parse('jour.xml') root = tree.getroot() # 定义CSV字段,结合加油站基础信息和油品信息 csv_fields = ['id_pdv', 'latitude', 'longitude', 'adresse', 'ville', 'carburant_nom', 'prix_valeur', 'maj_date'] with open('prix_carburants.csv', 'w', newline='', encoding='utf-8') as csvfile: writer = csv.DictWriter(csvfile, fieldnames=csv_fields) writer.writeheader() for pdv in root.findall('pdv'): # 提取加油站基础数据,处理空节点 base_data = { 'id_pdv': pdv.get('id'), 'latitude': pdv.get('latitude'), 'longitude': pdv.get('longitude'), 'adresse': pdv.find('adresse').text if pdv.find('adresse') is not None else '', 'ville': pdv.find('ville').text if pdv.find('ville') is not None else '' } # 遍历每个油品节点,生成一行CSV数据 for carburant in pdv.findall('carburant'): row = base_data.copy() row['carburant_nom'] = carburant.get('nom') row['prix_valeur'] = carburant.get('valeur') row['maj_date'] = carburant.get('maj') writer.writerow(row)
3. 调试小技巧
- 先截取少量XML片段测试,打印解析后的每一行数据,和原XML内容对比,确认字段对应正确。
- 检查CSV编码:用
utf-8编码保存,避免中文地址、城市名乱码。 - 如果直接从URL拉取数据,建议先下载XML到本地再测试,排除网络波动导致的解析异常。
内容的提问来源于stack exchange,提问作者user11278201
相关产品推荐
相关产品推荐

