使用PyShark捕获实时ARP包时如何动态更新计数器且无重复条目
ARP包计数去重实现方案
原代码问题点
already_seen去重判断限制了打印逻辑只有首次匹配到(mac,ip)对时才会执行,此时Counter刚完成首次计数,所以输出的计数永远为1keys字典定义在循环外属于冗余写法,每次循环都会覆盖之前的存储值- 不需要额外维护
already_seen列表,存储结构本身的键就可以记录所有出现过的唯一(mac,ip)对
修改后代码(捕获结束后输出不重复条目+总计数)
完全匹配「无重复条目、保留首次捕获时间、计数字段为对应数据包总数量」的需求,输出格式和原格式一致:
import pyshark from collections import defaultdict capture = pyshark.LiveCapture(interface='wlo2', bpf_filter='arp') capture.sniff(timeout=5) e_mac = '00:00:00:00:00:00' # 字典结构:key为(mac,ip)元组,value为[首次捕获时间, 总计数] arp_records = defaultdict(lambda: [None, 0]) for packet in capture: current_ip = packet.arp.dst_proto_ipv4 current_mac = packet.arp.dst_hw_mac # 过滤全0MAC if current_mac == e_mac: continue record_key = (current_mac, current_ip) # 首次出现时记录捕获时间 if arp_records[record_key][0] is None: arp_records[record_key][0] = packet.sniff_time # 每次收到对应包都更新计数 arp_records[record_key][1] += 1 # 统一输出所有不重复条目 for (mac, ip), (first_seen, cnt) in arp_records.items(): print(first_seen, cnt, mac, ip)
可选方案(实时动态更新条目)
如果需要收到数据包就实时刷新终端显示最新计数,不保留历史重复条目,可以加入清屏逻辑:
import pyshark from collections import defaultdict import os capture = pyshark.LiveCapture(interface='wlo2', bpf_filter='arp') e_mac = '00:00:00:00:00:00' arp_records = defaultdict(lambda: [None, 0]) # 持续捕获实时更新 for packet in capture.sniff_continuously(): current_ip = packet.arp.dst_proto_ipv4 current_mac = packet.arp.dst_hw_mac if current_mac == e_mac: continue record_key = (current_mac, current_ip) if arp_records[record_key][0] is None: arp_records[record_key][0] = packet.sniff_time arp_records[record_key][1] += 1 # 清屏后输出所有当前条目,实现动态刷新效果 os.system('clear') # Windows系统替换为 os.system('cls') for (mac, ip), (first_seen, cnt) in arp_records.items(): print(first_seen, cnt, mac, ip)
内容的提问来源于stack exchange,提问作者roXx
相关产品推荐
相关产品推荐

