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

代码仅将<ports>标签内首个开放端口写入CSV文件的问题咨询

解决Nmap XML解析仅导出首个开放端口的问题

问题重现

执行命令生成扫描结果:

nmap -sV -Pn -oX Output_3.xml scanme.nmap.org

用Python解析该XML文件时,仅能将<ports>标签内的首个开放端口写入detected_hosts.csv,其余开放端口全部丢失。

问题根源

原代码中所有端口相关的取值都用了[0]硬索引,只获取了第一个<port>元素的数据,完全没遍历当前主机下的所有端口,所以只会导出第一个开放端口的信息。

修复后的代码

import xml.etree.ElementTree as ET
import csv

def main():
    in_xml_port = 'Output_3.xml'  # 注意和生成的XML文件名保持一致
    xml_tree_port = ET.parse(in_xml_port)
    xml_root_port = xml_tree_port.getroot()
    
    # 写入CSV文件
    with open('detected_hosts.csv', 'w', newline='', encoding='utf-8') as file:
        writer = csv.writer(file)
        writer.writerow(['IP', 'Hostname', 'Status', 'Port', 'Service', 'Protocol', 'Product'])

        for host in xml_root_port.findall('host'):
            # 获取IP地址
            master_ip = host.find('address').get('addr')
            
            # 处理主机名:无主机名时用N/A替代
            master_hostname = 'N/A'
            hostnames_node = host.find('hostnames')
            if hostnames_node:
                hostname_node = hostnames_node.find('hostname')
                if hostname_node:
                    master_hostname = hostname_node.attrib['name']
            
            # 跳过无端口信息的主机
            ports_node = host.find('ports')
            if not ports_node:
                continue
            
            # 遍历当前主机的所有端口
            for port in ports_node.findall('port'):
                # 获取端口状态
                state_node = port.find('state')
                port_state = state_node.attrib['state'] if state_node else 'unknown'
                
                # 只处理开放端口
                if port_state != 'open':
                    continue
                
                # 获取端口号和协议
                port_id = port.attrib['portid']
                port_protocol = port.attrib['protocol']
                
                # 处理服务信息:无服务时用默认值
                service_node = port.find('service')
                service_name = service_node.attrib['name'] if service_node else 'unknown'
                product_name = service_node.attrib.get('product', 'N/A') if service_node else 'N/A'
                
                # 写入CSV行
                writer.writerow([master_ip, master_hostname, port_state, port_id, service_name, port_protocol, product_name])

if __name__ == '__main__':
    main()

关键修改点

  1. 遍历所有端口:移除原代码中[0]的硬索引,改为遍历当前主机下的每个<port>元素,确保所有开放端口都被处理
  2. 边界情况处理:增加了对无主机名、无端口信息、无服务信息的判断,避免因XML节点缺失导致的索引错误
  3. 简化逻辑:用find替代findall[0],代码更简洁且更安全
  4. 精准过滤:只在端口状态为open时写入数据,减少无效条目

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 18:45:19