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

Python实现Windows事件日志XML转CSV:数据提取失败排查

问题:Python提取Windows事件XML数据生成CSV为空

编写Python脚本从包含Windows事件及EventID的XML文件中提取指定数据,生成的CSV文件内容为空,数据提取环节执行失败。以下是原代码及XML示例片段:

原代码

from xml.etree import ElementTree as ET
import csv

tree = ET.parse("SecurityLog-rev2.xml")
root = tree.getroot() 

url = root[0].tag[:-len("Event")]
fieldnames = ['EventID']

with open ('event_log.csv', 'w') as csvfile:
    writecsv = csv.DictWriter(csvfile, fieldnames = fieldnames)
    writecsv.writeheader()

    for event in root:
        system = event.find(url + "System")
        output = {}
        fields = ['EventID']
   # for tag,att in fields:
   #     output[tag] = system.find(url + tag).attrib[att]

        if event.find(url + "EventData") != None:
            for data in event.find(url + "EventData"):
                name = data.attrib['Name']
                output[name] = data.text

        writecsv.writerow(output)

XML示例片段

<Event xmlns='http://schemas.microsoft.com/win/2004/08/events/event'><System><Provider Name='Microsoft-Windows-Security-Auditing' Guid='{54849625-5478-4994-A5BA-3E3B0328C30D}'/>
<EventID>4634</EventID>
<Version>0</Version><Level>0</Level><Task>12545</Task><Opcode>0</Opcode><Keywords>0x8020000000000000</Keywords><TimeCreated SystemTime='2011-04-16T15:07:53.890625000Z'/>
<EventRecordID>1410962</EventRecordID><Correlation/><Execution ProcessID='452' ThreadID='3900'/><Channel>Security</Channel><Computer>DC01.AFC.com</Computer><Security/></System>
<EventData><Data Name='TargetUserSid'>S-1-5-21-2795111079-3225111112-3329435632-1610</Data>
<Data Name='TargetUserName'>grant.larson</Data>
<Data Name='TargetDomainName'>AFC</Data><Data Name='TargetLogonId'>0x3642df8</Data><Data Name='LogonType'>3</Data></EventData></Event>

错误原因分析

  1. 未提取EventID:原代码注释了提取EventID的逻辑,导致output字典中没有EventID字段。而DictWriter指定的fieldnames仅包含EventID,写入时因无对应数据,生成空行。
  2. 字段不匹配:即使提取了EventData中的字段,这些字段不在fieldnames列表里,DictWriter默认不会写入未指定的字段,最终CSV只有表头,无数据。

修复后的代码

from xml.etree import ElementTree as ET
import csv

tree = ET.parse("SecurityLog-rev2.xml")
root = tree.getroot()

# 获取XML命名空间前缀
namespace = root[0].tag[:-len("Event")]
# 扩展fieldnames,包含需要的EventID和EventData字段
fieldnames = ['EventID', 'TargetUserSid', 'TargetUserName', 'TargetDomainName', 'TargetLogonId', 'LogonType']

with open('event_log.csv', 'w', newline='') as csvfile:
    writecsv = csv.DictWriter(csvfile, fieldnames=fieldnames)
    writecsv.writeheader()

    for event in root:
        output = {}
        # 提取System下的EventID
        system = event.find(namespace + "System")
        if system is not None:
            event_id_elem = system.find(namespace + "EventID")
            if event_id_elem is not None:
                output['EventID'] = event_id_elem.text
        
        # 提取EventData中的字段
        event_data = event.find(namespace + "EventData")
        if event_data is not None:
            for data in event_data:
                name = data.attrib.get('Name')
                if name and name in fieldnames:
                    output[name] = data.text
        
        # 写入一行数据(确保至少有EventID字段才写入)
        if output.get('EventID'):
            writecsv.writerow(output)

修复说明

  1. 正确提取EventID:从System元素下找到EventID子元素,通过.text获取其值,加入output字典。
  2. 扩展fieldnames:将需要的EventData字段加入fieldnames,确保DictWriter能写入这些列。
  3. 空值处理:添加对元素是否存在的判断,避免因元素不存在抛出异常;仅当提取到EventID时才写入行,过滤无效数据。
  4. 优化文件写入:添加newline=''参数,避免Windows下CSV出现空行。

内容的提问来源于stack exchange,提问作者PRobles

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 14:05:30