1. 程式人生 > >計算機網路實驗(二)之Wireshark抓包分析獲取URL列表(去重、排序、統計)

計算機網路實驗(二)之Wireshark抓包分析獲取URL列表(去重、排序、統計)

實驗要求

本試驗要求基於第一次實驗中訪問某官網主頁時所抓取到的資料包,用Python 3語言、Jupyter Notebook和Pyshark編寫程式碼進行協議分析所需的開發環境,編寫程式碼,以輸出的方式列出首頁以及其所包含的所有資源(至少包含如下型別 .html, .js, .css, .jpg, .jpeg, .png, .gif中每一類的所有資源)的URL。

實驗內容

一、下載安裝Anaconda3、Wireshark、Git Bash專案
由於下載步驟過於簡單,這裡不再贅述。自行百度。
二、配置環境變數
1、wireshark環境配置
將wireshark相關的程式所在的目錄的絕對路徑(比如c:\Program Files\Wireshark\)配置於系統的PATH環境變數裡。
2、Python(Anaconda)環境變數配置
為使Python能在任何目錄下的cmd進行呼叫執行程式,需要在Anaconda3安裝的過程中勾選如下選項 這裡寫dd描述 將Anaconda新增到系統環境變數中去。如果忘記勾選可以在計算機->右鍵屬性->高階系統設定->環境變數->path,將anaconda的安裝目錄新增到path中去。 這裡寫圖片描述
三、更新pip
在開始選單裡找到 Anaconda3 ,點選 Anaconda Prompt ,然後在出來的cmd命令列窗口裡輸入下列命令並回車:python -m pip install -U pip 這裡寫圖片描述
由於在很早之前就已經更新過,所以上圖顯示已經更新。

四、檢出程式碼

1、執行git bash,用cd命令切換到D盤(前提是你係統有D盤),mkdir src建立src目錄,用cd命令切換到想用來放原始碼的目錄/d/src裡:cd /d/src 2、切換到anaconda prompt裡去手動安裝pyshark需要的依賴:pip install –trusted-host pypi.org logbook py lxml 這裡寫圖片描述 3、回到git bash從github.com克隆(檢出)程式碼 git clone https://github.com/md11235/pyshark.git

這裡寫圖片描述

五、解除安裝已有的pyshark,安裝從github拿到的程式碼
1、執行anaconda prompt 2、解除安裝pyshark:pip uninstall pyshark 這裡寫圖片描述 由於我之前並未安裝所以顯示直接跳過 3、在anaconda prompt裡從檢出的原始碼安裝pyshark,用如下命令切換到d:\src : d: cd d:\src\pyshark\src 然後執行 python setup.py install 這裡寫圖片描述 前期工作準備完畢。

程式碼實現

  • 1、獲取所有資源URL

要想對抓取的資料包進行分析,方式之一就是匯入pyshark模組,PyShark的強大在於可以呼叫tshark內建的所有資料包解碼器。利用pyshark提供的FileCapture方法可獲得一個Capture 物件。在捕獲(capture)和資料包(packet)層面就會有多個方法和屬性可用。其中就有一個數據包屬性叫做http,再呼叫其request_full_uri屬性就可以獲得相應資源的完整URL。 我們先來看下URL構成:模式(或協議)+伺服器主機地址(IP地址)+埠+路徑+引數。它指向的是某臺伺服器上資源的超連結。我們都知道每個檔案都會有他獨有的字尾名來標記他是何種型別的檔案。

def getUrlList():
    urlList = []
    for pkt in cap:
        try:
            url = pkt.http.request_full_uri
            if (url[len(url) - 1] == "/"):
                urlList.append(("html", url))#首頁HTML資源,應考慮網站省略的檔案部分路徑,此處預設為HTML檔案資源(其實不一定預設為HTML檔案)
            else:
                urlList.append((url.split(".")[len(url.split(".")) - 1].split("?")[0], url))
        except:
            continue
    return urlList

所以在上面定義了getUrlList函式,主要功能是獲取所有資源URL列表並返回。利用了字串的分割函式split以“.”來分割,取出其返回的字串列表中的最後一個便是請求的檔案的型別。由於我們不知道到底能夠獲得多少種資源型別的檔案,即使知道,我們也不建議把它寫死。然後將獲取的檔案型別和URL存入列表中返回,以供後面的排序查重使用。 為顯示結果,定義了printUrlList函式:

def printUrlList(obj):
    i = 1
    for tup in obj:
        print(i, tup[0], tup[1])
        i += 1

執行,呼叫方式:printUrlList(getUrlList()) 程式執行結果部分截圖: 這裡寫圖片描述

  • 2、排序分類

由上面的執行結果可以看出,預設是以請求的時間排序的。個人感覺非常的不爽,非常凌亂,所以想能不能對其進行分類和排個序呢?於是自己寫了個函式,以檔案的型別來排序。

def sort(obj, isReverse):
    if (isReverse):
        print("以型別逆序排列")
    else:
        print("以型別順序排列")
    return sorted(obj, key=lambda x: x[0], reverse=isReverse)

函式有兩個引數:obj是要進行排序的元組,isReverse代表是否逆序排列,為True時逆序,False順序排列。 執行,呼叫方式:printUrlList(sort(getUrlList(),True)) 執行結果部分截圖: 這裡寫圖片描述 由執行結果可以看出我們在做排序的時候,同時也對其進行了分類。

  • 3、資源去重

在上面執行結果中 這裡寫圖片描述 這裡寫圖片描述

我們發現http://s.pc.qq.com/pcmgr/zonedword/gjzonedword20150522.js出現了多次,這不經意間讓我想起,在我們在抓包的時候可能會訪問某個網址多次,然而我們在整理資源的時候並不希望出現重複的資料。所以又定義了一個函式對其進行了過濾去重,並對其進行了按型別順序排列。

def getNoAndRepeatUrl(ls, isReverse):           
    d = {}
    noRepeatUrl = []
    repeatUrl = []
    for k in ls:
        if k[1] in d:
            d[k[1]] += 1
        else:
            d[k[1]] = 1
    for k in d:
        if d[k] > 1:
            repeatUrl.append(("重複URL:" + str(k), "重複數:" + str(d[k]-1)))
        if (k[len(k) - 1] == "/"):
            noRepeatUrl.append(("html", k))
        else:
            noRepeatUrl.append((k.split(".")[len(k.split(".")) - 1].split("?")[0], k))
    printUrlList(repeatUrl)
    print("去重後所有資源URL")
    printUrlList(sort(noRepeatUrl, isReverse))

函式包含兩個引數:ls表示要傳入的url列表,函式有兩個引數:obj是要進行排序的元組,isReverse代表是否逆序排列,為True時逆序,False順序排列。 執行,呼叫方式:getNoAndRepeatUrl(getUrlList(),False) 執行結果部分截圖: 這裡寫圖片描述 ………………………………………………………………………………………………….. 這裡寫圖片描述 由以上執行結果可以看出http://s.pc.qq.com/pcmgr/zonedword/gjzonedword20150522.js重複了5次,http://www.git.edu.cn/system/dwr/call/plaincall/PageCounterDWR.getVisittime.dwr重複了一次,去重後的總數為75,加上重複的6條剛好等於沒去重前的81條。完美!

  • 4、統計

實驗進行到這,我的內心並沒有得到滿足。我們在管理一大堆事情的時候總期待得到一個統計的結果。 於是三下五除二,手寫了個函式

def getAllTypeCount(ls):
    d = {}
    for k in ls:
        if k[0] in d:
            d[k[0]] += 1
        else:
            d[k[0]] = 1
    return d

函式只有一個引數ls:需要傳入的資源URL列表 執行,呼叫方式:getAllTypeCount(getUrlList()) 執行結果截圖:

這裡寫圖片描述

總結

本文主要涉及了Python列表、元祖、lambda 表示式,pyshark模組的使用,程式碼較為簡單,存在諸多不足,如果你有更好的程式碼實現和建議,請在下方進行評論,交流。