如何使用Pyshark将多个pcapng文件转换为CSV格式?
将多个pcapng文件转换为CSV的Python实现(解决DataFrame输出为空问题)
希望通过Python将多个pcapng文件转换为CSV格式,不确定是否可通过Pyshark实现,未找到相关文档。曾尝试用Scapy和Pyshark提取数据包字段并存入DataFrame,但输出结果为空。尝试的代码如下:
for packet in capture: # Extract necessary fields from each packet and append to the data list time = packet.sniff_time.timestamp if time is not None and isinstance(time, (int, float, str)): # Check if the timestamp is valid time = float(time) else: continue if 'IP' not in packet: # Skip non-IP packets continue src = packet['ip'].src dst = packet['ip'].dst proto = packet['ip'].proto length = int(packet.length) info = '' try: if 'DATA' in packet and hasattr(packet, 'data'): info = packet.data.data_raw.decode('utf-8', errors='ignore') except UnicodeDecodeError: pass data.append((time, src, dst, proto, length, info))
输出为空的核心原因是数据包对象的属性调用逻辑错误——Scapy和Pyshark的packet结构差异极大,混用属性会导致字段提取失败,最终没有数据存入列表。另外如果capture对象初始化错误(比如未正确加载pcapng文件),也会直接导致无数据输出。
以下是两种工具的可行实现方案:
一、用Scapy实现(轻量高效)
Scapy原生支持pcapng格式,修正后的批量处理代码如下:
from scapy.all import rdpcap import pandas as pd import os def pcapng_to_csv_scapy(pcapng_files, output_csv): data = [] for file in pcapng_files: # 加载pcapng文件 capture = rdpcap(file) for packet in capture: # 提取时间戳(Scapy返回直接为float类型) time = packet.time # 过滤非IP数据包 if not packet.haslayer('IP'): continue src = packet['IP'].src dst = packet['IP'].dst proto = packet['IP'].proto # 获取数据包总长度 length = len(packet) # 提取负载内容(Scapy中用Raw层标识数据段) info = '' if packet.haslayer('Raw'): try: info = packet['Raw'].load.decode('utf-8', errors='ignore') except: pass data.append([time, src, dst, proto, length, info]) # 转为DataFrame并保存为CSV df = pd.DataFrame(data, columns=['timestamp', 'src_ip', 'dst_ip', 'protocol', 'length', 'payload']) df.to_csv(output_csv, index=False) # 示例:批量处理当前目录下所有pcapng文件 pcapng_files = [f for f in os.listdir('.') if f.endswith('.pcapng')] pcapng_to_csv_scapy(pcapng_files, 'output_scapy.csv')
二、用Pyshark实现(支持复杂协议解析)
Pyshark完全可以处理pcapng文件,需遵循Wireshark的解析逻辑调用属性,代码如下:
import pyshark import pandas as pd import os def pcapng_to_csv_pyshark(pcapng_files, output_csv): data = [] for file in pcapng_files: # 加载pcapng文件,启用JSON解析避免格式异常 capture = pyshark.FileCapture(file, use_json=True, include_raw=True) for packet in capture: # 提取时间戳(注意是调用timestamp()方法) try: time = float(packet.sniff_time.timestamp()) except: continue # 过滤非IP数据包 if not hasattr(packet, 'ip'): continue src = packet.ip.src dst = packet.ip.dst proto = packet.ip.proto # 获取数据包长度 length = int(packet.length) # 提取负载内容(Pyshark中数据层可能叫data或payload) info = '' if hasattr(packet, 'data'): try: info = packet.data.data_raw.decode('utf-8', errors='ignore') except: pass elif hasattr(packet, 'payload'): try: info = packet.payload.payload_raw.decode('utf-8', errors='ignore') except: pass data.append([time, src, dst, proto, length, info]) df = pd.DataFrame(data, columns=['timestamp', 'src_ip', 'dst_ip', 'protocol', 'length', 'payload']) df.to_csv(output_csv, index=False) # 示例:批量处理当前目录下所有pcapng文件 pcapng_files = [f for f in os.listdir('.') if f.endswith('.pcapng')] pcapng_to_csv_pyshark(pcapng_files, 'output_pyshark.csv')
关键修正说明
Scapy侧:
- 用
rdpcap()加载pcapng文件,原生支持无需额外配置 - 用
packet.haslayer('IP')判断IP包,而非'IP' in packet - 数据包长度用
len(packet)获取,而非packet.length - 负载内容通过
Raw层的load属性提取
- 用
Pyshark侧:
- 初始化
FileCapture时添加use_json=True避免解析异常 - 用
hasattr(packet, 'ip')判断IP层,而非'IP' in packet - 时间戳需调用
timestamp()方法(原代码少了括号) - 数据层属性名可能随协议变化,需多维度判断
- 初始化
内容的提问来源于stack exchange,提问作者Michael GT
相关产品推荐
相关产品推荐

