You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 15:50:29