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

Python解析OWASP ZAP XML报告并导出Excel的最优方案咨询

问题解决:OWASP ZAP XML解析优化与Excel导出实现

一、XML解析代码评估与优化

当前代码的问题

  1. 临时数据存储风险:用实例变量self.site_name等存储单条站点信息,多文件/多站点循环时,若某轮未找到site节点,会残留上一轮数据。
  2. XPath路径冗余:site.findall('.//alertitem')会遍历整个XML文档查找节点,应该使用更精确的路径限制在当前site节点下,提升效率。
  3. 数据结构可读性差:用列表存储站点和漏洞信息,后续处理字段时易出错,且难以维护。
  4. 缺少异常处理:若XML中某个标签缺失(比如instances为空),alert.find('instances').text会直接抛出AttributeError。
  5. 文件遍历不严谨:os.listdir会返回目录,未做文件类型二次判断,可能导致解析出错。

优化后的代码

使用dataclasses定义结构化数据,结合glob筛选文件,添加异常处理,采用精确XPath:

from dataclasses import dataclass
import glob
import os
import xml.etree.ElementTree as Et

@dataclass
class Site:
    name: str
    host: str
    port: str
    ssl: str

@dataclass
class Alert:
    site_host: str
    site_port: str
    site_ssl: str
    name: str
    risk_code: str
    confidence: str
    risk_desc: str
    confidence_desc: str
    desc: str
    instances: str
    ref: str

class ZAPReportParser:
    def __init__(self, zap_folder):
        self.path_zap = zap_folder
        self.sites: list[Site] = []
        self.alerts: list[Alert] = []

    def process_xml_folder(self):
        # 用glob直接筛选XML文件,替代手动判断
        for xml_path in glob.glob(os.path.join(self.path_zap, "*.xml")):
            tree = Et.parse(xml_path)
            root = tree.getroot()

            for site in root.findall('.//site'):
                # 用局部变量存储当前站点数据,避免实例变量污染
                site_name = site.get('name', '')
                site_host = site.get('host', '')
                site_port = site.get('port', '')
                site_ssl = site.get('ssl', '')
                self.sites.append(Site(site_name, site_host, site_port, site_ssl))

                # 精确查找当前site下的alertitem节点(匹配ZAP XML结构)
                for alert in site.findall('./alerts/alertitem'):
                    # 用findtext方法,标签不存在时返回默认空字符串,避免报错
                    alert_ref = alert.findtext('alertRef', '')
                    alert_name = alert.findtext('alert', '')
                    alert_risk_code = alert.findtext('riskcode', '')
                    alert_confidence = alert.findtext('confidence', '')
                    alert_risk_desc = alert.findtext('riskdesc', '')
                    alert_confidence_desc = alert.findtext('confidencedesc', '')
                    alert_desc = alert.findtext('desc', '')
                    alert_instances = alert.findtext('instances', '')

                    self.alerts.append(Alert(
                        site_host=site_host,
                        site_port=site_port,
                        site_ssl=site_ssl,
                        name=alert_name,
                        risk_code=alert_risk_code,
                        confidence=alert_confidence,
                        risk_desc=alert_risk_desc,
                        confidence_desc=alert_confidence_desc,
                        desc=alert_desc,
                        instances=alert_instances,
                        ref=alert_ref
                    ))

二、xlsxwriter导出Excel格式实现

要实现每个漏洞包含全量信息的表格,只需将结构化的Alert数据逐行写入Excel,还可添加格式优化(比如高风险项高亮):

import xlsxwriter

def export_alerts_to_excel(alerts: list[Alert], output_path):
    workbook = xlsxwriter.Workbook(output_path)
    worksheet = workbook.add_worksheet("ZAP漏洞报告")

    # 定义表头
    headers = [
        "主机", "端口", "是否SSL", "漏洞名称", "风险代码",
        "可信度", "风险描述", "可信度描述", "漏洞详情", "实例", "漏洞参考"
    ]

    # 定义格式:表头加粗灰色填充,高风险项红色填充
    header_format = workbook.add_format({'bold': True, 'align': 'center', 'valign': 'vcenter', 'bg_color': '#D3D3D3'})
    high_risk_format = workbook.add_format({'bg_color': '#FFC7CE'})

    # 写入表头
    for col, header in enumerate(headers):
        worksheet.write(0, col, header, header_format)

    # 设置列宽,避免内容被截断
    worksheet.set_column(0, 0, 15)
    worksheet.set_column(1, 1, 8)
    worksheet.set_column(2, 2, 10)
    worksheet.set_column(3, 3, 30)
    worksheet.set_column(4, 4, 10)
    worksheet.set_column(5, 5, 10)
    worksheet.set_column(6, 6, 20)
    worksheet.set_column(7, 7, 20)
    worksheet.set_column(8, 8, 50)
    worksheet.set_column(9, 9, 50)
    worksheet.set_column(10, 10, 15)

    # 写入漏洞数据
    for row, alert in enumerate(alerts, start=1):
        row_data = [
            alert.site_host, alert.site_port, alert.site_ssl, alert.name, alert.risk_code,
            alert.confidence, alert.risk_desc, alert.confidence_desc, alert.desc, alert.instances, alert.ref
        ]
        for col, value in enumerate(row_data):
            # 风险代码为3(高风险)时应用红色格式
            cell_format = high_risk_format if col == 4 and value == '3' else None
            worksheet.write(row, col, value, cell_format)

    workbook.close()

使用示例

if __name__ == "__main__":
    parser = ZAPReportParser("/path/to/zap/xml/reports")
    parser.process_xml_folder()
    export_alerts_to_excel(parser.alerts, "zap_vulnerabilities.xlsx")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 10:52:20