Python脚本XML转CSV:将输出改为表格列格式
问题:将XML提取的键值对转为CSV表格格式
我有一段Python脚本,用来提取XML数据并导出到CSV文件。当前脚本输出是逐行键值对形式(如示例2),但需要改成示例1那样的表格列格式——表头为字段名,每行对应一条完整事件数据。
示例1(期望输出)
EventID,TargetUserSid,TargetUserName,TargetDomainName,TargetLogonId 4634, S-1-5-21-2795111079-3225111112-3329435632-1610,grant.larson,AFC,0x3642df8
示例2(当前输出)
EventID 4634 TargetUserSid S-1-5-21-2795111079-3225111112-3329435632-1610 TargetUserName grant.larson TargetDomainName AFC TargetLogonId 0x3642df8 LogonType 3
现有脚本
from xml.etree import ElementTree as ET import pandas as pd import csv tree = ET.parse("SecurityLog-rev2.xml") root = tree.getroot() ns = "{http://schemas.microsoft.com/win/2004/08/events/event}" data = [] for eventID in root.findall(".//"): if eventID.tag == f"{ns}System": for e_id in eventID.iter(): if e_id.tag == f'{ns}EventID': row = "EventID", e_id.text data.append(row) if eventID.tag == f"{ns}EventData": for attr in eventID.iter(): if attr.tag == f'{ns}Data': #print(attr.attrib) row = attr.get('Name'), attr.text data.append(row) df = pd.DataFrame.from_dict(data, orient='columns') df.to_csv('event_log.csv', index=False, header=False) print(df)
解决方案
原脚本的核心问题是没有按单条事件分组,把所有键值对都塞进了一个扁平列表。修改思路为:遍历每个事件节点,为每个事件单独创建字典存储所有字段,最后将所有事件字典转为DataFrame生成CSV。
修改后的脚本
from xml.etree import ElementTree as ET import pandas as pd tree = ET.parse("SecurityLog-rev2.xml") root = tree.getroot() ns = "{http://schemas.microsoft.com/win/2004/08/events/event}" # 存储所有事件的列表,每个元素对应一条事件的字段字典 events = [] # 遍历XML中的每个<Event>节点 for event in root.findall(f".//{ns}Event"): event_dict = {} # 提取System节点下的EventID system_node = event.find(f"{ns}System") if system_node: event_id_node = system_node.find(f"{ns}EventID") if event_id_node: event_dict["EventID"] = event_id_node.text # 提取EventData节点下的所有Data字段(带Name属性) event_data_node = event.find(f"{ns}EventData") if event_data_node: for data_node in event_data_node.findall(f"{ns}Data"): field_name = data_node.get('Name') field_value = data_node.text if field_name: event_dict[field_name] = field_value # 仅当事件字典有内容时加入列表 if event_dict: events.append(event_dict) # 转换为DataFrame并导出CSV,自动用字典键作为表头 df = pd.DataFrame(events) df.to_csv('event_log.csv', index=False) print(df)
关键改动说明
- 按事件分组:以
<Event>节点为单位创建字典,确保一条事件的所有字段都归属同一数据项。 - 优化节点查找:用
find和findall精准定位目标节点,避免遍历整个XML树,提升效率。 - 自动生成表头:DataFrame会自动将字典的键作为CSV表头,无需手动指定。
- 过滤无效数据:仅当Data节点的
Name属性存在时才加入字典,避免空字段干扰。
内容的提问来源于stack exchange,提问作者PRobles
相关产品推荐
相关产品推荐

