工控协议数据处理这个专题主要是记录一下自己的大数据作业,我选了工控协议数据作为处理对象,使用Python进行处理,用了BeautifulSoup包爬取数据。使用了Pyshark解析协议数据包。

爬取数据

第一步爬取协议数据,网址我就不放出来了,有需要的可以联系我。

爬虫规则:匹配所有<a>标签中“herf”字段是以“.cap”或“.pcap”结尾的链接,并以模拟浏览器的方式将链接的文件下载到本地。代码如下:

from bs4 import BeautifulSoup
from urllib import request
import wget
import re
#模拟浏览器访问头
hdr = {'User-Agent': 'Mozilla/5.0'}
#不加headers参数的话,有些网站会拒绝访问,这里我们模拟浏览器访问
req = request.Request("",headers=hdr)
html = request.urlopen(req)
soup = BeautifulSoup(html, 'lxml')
index_href=0
def href_match(href):
    #正则匹配,匹配herf属性里以.cap或者.pcap结尾的文件。大家可以根据自己的需求进行修改
    return href and re.compile("\\.[p,\\.]*cap$").search(href)
for hreffind in soup.find_all(href=href_match):
    index_href=index_href+1
    print(hreffind.attrs['href'])
    url = ''+hreffind.attrs['href']
    print(url)
    hdr = {'User-Agent': 'Mozilla/5.0'}
    req = request.Request(url,headers=hdr)
    #下载文件,保存到当前目录的data目录里,按照下载顺序命名
    html1 = request.urlopen(req)
    with open('./data/'+str(index_href), 'wb') as f:
        f.write(html1.read())

数据预处理和保存

协议数据包一般都有很多层,每层一般也会很多字段,但需要统计的关键字段并不多,所以要对数据包进行预处理,我们利用pyshark工具包对数据包进行解析。

为了统计并存储每种协议的出现次数,平均长度和分层结构。我们构建了一个类用来存储每种协议的相关信息,类中包含协议名、平均长度、分层信息、出现次数四个属性和一个用于打印该协议相关信息的方法。为了实现对协议信息的快速查询,我们使用了python中的字典结构来存储协议信息。

由于数据量较大,预处理需要消耗一定的时间,所以我们将预处理后的数据导出为csv文件,在数据分析时直接读取可以节省时间。代码如下:

import pyshark
import pandas as pd
import matplotlib
matplotlib.rcParams['font.sans-serif'] = [u'SimHei']
matplotlib.rcParams['axes.unicode_minus'] = False
#定义了一个协议类,里面包括协议的名称,协议的平均长度,协议的层数,该协议在爬取的数据中出现的次数
class Protocol(object):
    def __init__(self, name, layers,length,number):
        self.name = name
        self.length = length
        self.layers = layers
        self.number = number
    def printinfo(self):
        print('Protocol:%s,%s,%s,%s' % (self.name, self.length,self.layers,self.number))
protocol_dict={}
k_meansm=[]
u=0
index2key=[]
hlayer=''
for index in range(1,324):
    #使用了pyshark来解析协议
    cap=pyshark.FileCapture("./data/"+str(index))
    for cap_ in cap:
        hlayer=str.upper(cap_.highest_layer)
        if hlayer=='DATA':
            hlayer=str.upper(cap_.layers[-2].layer_name)            
            #print(hlayer)
        if hlayer not in protocol_dict:
            new_pro=Protocol(hlayer,cap_.layers,int(cap_.length),1)
            protocol_dict[hlayer]=new_pro
        else:
            protocol_dict[hlayer].number=protocol_dict[hlayer].number+1
            protocol_dict[hlayer].length=protocol_dict[hlayer].length+int(cap_.length)
    cap.close_async()

#写入csv文件
for key in protocol_dict:
    k_meansm.append([key,(protocol_dict[key].length/protocol_dict[key].number),len(protocol_dict[key].layers),protocol_dict[key].layers,protocol_dict[key].number])
column=['name','ave_length','layers_count','layers','number']
data_processed=pd.DataFrame(columns=column,data=k_meansm)
data_processed.to_csv('./data_processed.csv')


说点什么
支持Markdown语法
好耶,沙发还空着ヾ(≧▽≦*)o
Loading...