使用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()
关键修改点
- 替换错误的键访问:把
port_dict[3]改为host_data.get('ports', []),用get方法可以在目标主机没有端口数据时返回空列表,避免额外报错。 - 过滤非主机条目:扫描结果里包含
runtime、stats等非主机相关的键,需要跳过这些条目,避免遍历无效数据。 - 筛选开放端口:增加
port.get('state') == 'open'的判断,确保只提取真正开放的端口数据。 - 提取完整端口信息:除了端口号,还提取了协议、服务名、开放原因等实用数据,满足自动化脚本的更多需求。
运行效果
执行脚本后,会输出每个开放端口的详细信息,比如:
开放端口信息: 端口 21/tcp:服务 ftp,开放原因:syn-ack 端口 80/tcp:服务 http,开放原因:syn-ack
内容的提问来源于stack exchange,提问作者Nathanule Gibb
相关产品推荐
相关产品推荐

