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

使用nmap3库提取嵌套字典开放端口数据时遇KeyError问题求助

解决nmap3库提取开放端口时的KeyError: 3问题

错误原因

你的代码里用port_dict[3]尝试获取端口数据,但nmap3返回的扫描结果字典中,目标主机的端口列表存储在**ports**字符串键下,而非数字索引3。从你提供的扫描结果结构能明显看到,每个IP对应的字典里根本不存在3这个键,直接访问必然触发KeyError。

修正后的代码

import nmap3
from sys import argv

class Scanner():
    def __init__(self, target_ip, output_name):
        self.target_ip = target_ip
        self.output_name = output_name

    # 扫描所有TCP端口并提取开放端口数据
    def initial_scan(self):
        nmap = nmap3.NmapScanTechniques()
        open_ports = []
        tcp_scan_result = nmap.nmap_tcp_scan(target=self.target_ip, args="-p- --min-rate 1500")
        
        for host, host_data in tcp_scan_result.items():
            # 跳过非主机条目(比如runtime、stats这些)
            if host in ['runtime', 'stats', 'task_results']:
                continue
            # 获取端口列表,没有则返回空列表避免报错
            ports = host_data.get('ports', [])
            for port in ports:
                # 只提取状态为open的端口
                if port.get('state') == 'open':
                    port_info = {
                        'portid': port['portid'],
                        'protocol': port['protocol'],
                        'service': port['service']['name'],
                        'reason': port['reason']
                    }
                    open_ports.append(port_info)
        
        # 打印提取的开放端口详细数据
        print("开放端口信息:")
        for info in open_ports:
            print(f"端口 {info['portid']}/{info['protocol']}:服务 {info['service']},开放原因:{info['reason']}")
        # 如果只需要端口号列表,用下面的代码
        # port_ids = [p['portid'] for p in open_ports]
        # print("开放端口号列表:", port_ids)

if __name__ == "__main__":
    target_ip = argv[1]
    output_name = argv[2]
    scanner = Scanner(target_ip, output_name)
    scanner.initial_scan()

关键修改点

  1. 替换错误的键访问:把port_dict[3]改为host_data.get('ports', []),用get方法可以在目标主机没有端口数据时返回空列表,避免额外报错。
  2. 过滤非主机条目:扫描结果里包含runtime、stats等非主机相关的键,需要跳过这些条目,避免遍历无效数据。
  3. 筛选开放端口:增加port.get('state') == 'open'的判断,确保只提取真正开放的端口数据。
  4. 提取完整端口信息:除了端口号,还提取了协议、服务名、开放原因等实用数据,满足自动化脚本的更多需求。

运行效果

执行脚本后,会输出每个开放端口的详细信息,比如:

开放端口信息:
端口 21/tcp:服务 ftp,开放原因:syn-ack
端口 80/tcp:服务 http,开放原因:syn-ack

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 09:20:30