Scapy异常:格式字符串条件错误,求抓包脚本问题解析
解决Scapy sprintf格式字符串错误的问题
这个错误的核心原因是你把Python的字符串format方法和Scapy自带的sprintf语法混在一起使用了,导致Scapy解析格式字符串时出现冲突。
为什么会出错?
Scapy的sprintf方法有自己的格式规则(用%FieldName%来提取数据包字段),而你在传给它的字符串里先用format插入了解码后的负载内容。这种混合写法会让Scapy误判格式字符串的结构,从而抛出"Bad condition in format string: []"的错误。另外你的代码还遗漏了sys模块的导入,触发KeyboardInterrupt时会额外报错。
修正后的解决方案
我们可以把地址字段的提取和负载解码分开处理,避免两种格式语法冲突,同时优化负载获取的逻辑(确保只提取实际的数据包负载):
方案一:拆分sprintf与负载拼接
from scapy.all import * import sys # 补充导入sys模块 def decode(rawload): # 优化解码逻辑:优先尝试UTF-8解码,失败则保留原始内容 try: return rawload.decode('utf-8', errors='replace') except AttributeError: # 若payload不是bytes类型,直接转为字符串 return str(rawload) try: def packet_handler(pkt): # 先用sprintf提取地址信息 addr_output = pkt.sprintf("src: %IP.src% (%Ether.src%) receiver: %IP.dst%") # 检查是否存在Raw层(实际负载),避免无负载时出错 payload = decode(pkt[Raw].load) if Raw in pkt else "No payload" # 拼接最终输出 print(f"{addr_output} load: {payload}") # 启动嗅探 sniff(iface="wlan0", filter="host 192.168.1.13", prn=packet_handler) except KeyboardInterrupt: print("\n嗅探已终止。") sys.exit(1)
方案二:完全手动构造输出(更直观)
如果你觉得sprintf的语法不够灵活,也可以直接提取数据包字段来构造输出:
from scapy.all import * import sys def decode(rawload): try: return rawload.decode('utf-8', errors='replace') except AttributeError: return str(rawload) try: def packet_handler(pkt): # 先确认数据包包含IP层 if IP in pkt: src_ip = pkt[IP].src dst_ip = pkt[IP].dst src_mac = pkt[Ether].src # 获取实际负载 payload = decode(pkt[Raw].load) if Raw in pkt else "No payload" print(f"src: {src_ip} ({src_mac}) receiver: {dst_ip} load: {payload}") sniff(iface="wlan0", filter="host 192.168.1.13", prn=packet_handler) except KeyboardInterrupt: print("\n嗅探已终止。") sys.exit(1)
额外提示
- 不是所有数据包都有负载(比如TCP的ACK包),所以一定要检查
Raw层是否存在,避免抛出属性错误。 - 后续可以优化
decode函数,根据不同的协议(HTTP、TCP等)针对性解码负载内容,提升可读性。
内容的提问来源于stack exchange,提问作者rockstar1820
相关产品推荐
相关产品推荐

