APP系列爬蟲2-mitmproxy安裝與簡介

我們通常使用的抓包工具就是Fiddler和Charles這種圖形化的,Charles的優點是跨平臺,Windows和Mac都可以使用,Fiddler的優點是功能“極其”強大,不僅擁有抓包功能,還擁有中間人攻擊的功能,但是使用成本太高了,我們做爬蟲開發,使用到Fiddler的功能不過十之二三罷了。今天我們主要講的是mitmproxy這款工具,這是一款專業的中間人攻擊工具,mitmproxy 不僅可以截獲請求幫助開發者查看、分析,最最重要的是支持Python進行定製化二次開發。例如:截獲瀏覽器的請求內容,並將數據處理後存儲到數據庫,再將內容交給瀏覽器;如果出現異常時,發出郵件通知,並返回給瀏覽器一個空的頁面。mitmproxy有以下幾個特點:

  • 像正常代理一樣轉發請求,保證服務器和客戶端之間的通信
  • 可以攔截請求/返回,並可以修改請求/返回
  • 可以加載Python腳本執行

安裝mitmproxy

<code>pip install mitmproxy/<code>

在Python環境中安裝使用pip最為簡潔。mitmproxy安裝完成以後會包含三個工具:mitmproxymitmdumpmitmweb。安裝完成以後直接在控制檯輸入mitmproxy --version就可以查看版本信息。

APP系列爬蟲2-mitmproxy安裝與簡介


查看版本信息

注意如果是在Windows系統中安裝,需要先安裝Microsoft Visual C++ V14.0以上版本,並且mitmproxy是不能在Windows系統中進行抓包的,在執行mitmproxy --version命令的時候會得到一個錯誤提示。

<code>Error: mitmproxy's console interface is not supported on Windows. You can run mitmdump or mitmweb instead./<code>

在Windows系統中我們主要使用的是安裝完以後的另外兩個工具mitmdump和mitmweb。

安裝瀏覽器代理插件SwitchyOmega

為什麼要先安裝瀏覽器代理插件呢?因為我們在使用抓包工具的時候,必須要通過代理訪問網絡,才能抓到包,可以通過設置系統代理的方式來實現,但是直接設置瀏覽器代理會更加方便,而且使用代理插件我們可以配置多種代理模式。Chrome瀏覽器安裝插件需要科學上網,只要在度娘搜索谷歌上網助手,安裝以後重啟瀏覽器,就可以訪問谷歌商店來安裝插件了,插件我們這裡推薦SwitchyOmega。安裝完以後要進行設置。

  • 打開選項
    打開設置項
  • 新建情景模式
APP系列爬蟲2-mitmproxy安裝與簡介

  • 設置代理地址和端口
APP系列爬蟲2-mitmproxy安裝與簡介

然後在瀏覽器中訪問地址前,先選擇代理方式,再進行訪問

APP系列爬蟲2-mitmproxy安裝與簡介

安裝證書

正常情況下,mitmproxy啟動後,只能抓取到HTTP請求的信息,我們要抓取HTTPS請求信息需要安裝證書。證書安裝有兩種方式:

第一種

  • 首先打開mitmproxy進行抓包,即運行: mitmproxy或者另外兩個命令
  • 訪問http://mitm.it/

如果你沒有打開mitmproxy進行抓包的話,在這一步你會得到如下錯誤

APP系列爬蟲2-mitmproxy安裝與簡介

上面這種方法我一直訪問不到mitm.it這個頁面,可以採用以下方式進行安裝

第二種

  • 首先打開mitmproxy進行抓包,即運行: mitmproxy或者另外兩個命令。執行了這一步以後,在操作系統對應的用戶名目錄下會產生一個.mitmproxy目錄
APP系列爬蟲2-mitmproxy安裝與簡介

.cer是Mac或Linux下的證書,.p12是Windows下的證書,.pem是安卓下的證書。

通過上述兩種方式得到證書文件後,證書按照步驟在網上找,非常多,這裡就不再敖述了。

使用mitmproxy

要啟動 mitmproxy 用 mitmproxy、mitmdump、mitmweb 這三個命令中的任意一個即可,這三個命令功能一致,且都可以加載自定義腳本,唯一的區別是交互界面的不同。但是他們各有特點,mitmproxy是進行抓包調試使用的,mitmweb是mitmproxy的可視版本,mitmdump主要是加載腳本執行的,因為mitmdump抓取的信息是不主動顯示的,由我們在腳本中使用特定打印方式,輸出到界面,方便我們調試,當然也可以直接使用print打印。

在控制檯中輸入mitmdump -h,可以查看命令行幫助,我們主要使用的是-s和-p參數,-p指定監聽端口,默認端口為8080,如果和其他軟件有衝突,可以通過此參數修改;-s指定執行腳本,這個就是我們用mitmproxy的主要作用,通過加載腳本,執行請求過程的中間處理,修改請求數據或者保存返回數據。目前有兩種使用方式:

<code>from mitmproxy import httpfrom mitmproxy import ctxdef response(flow: http.HTTPFlow):    """    flow為參數,後面跟http.HTTPFlow表示聲明其類型,    這樣在IDE中就可以自動提示其屬性和方法,這是Python為我們提供的一種    便攜的方式,尤其是對外提供接口時,可以告知參數類型,這種方式是可選    的,當然你也可以使用常用方式,即不知道參數類型,只寫參數名即可    """    ctx.log.info(flow.request.url)    ctx.log.warn(flow.request.headers)/<code> 

mitmproxy.ctx.log為mitmproxy為我們提供的日誌打印方式。

<code>from mitmproxy import httpclass Counter:    def __init__(self):        self.num = 0    def request(self, flow: http.HTTPFlow):        self.num += 1        print("We've seen %d flows" % self.num)        print(flow.request.url)        print(flow.request.query)addons = [    Counter()]/<code>

官方推薦使用類的方式,上面的代碼可能讓你有點迷茫,無論是使用類方式還是函數方式def reqeust函數都是在mitmdump內部回調時會調用的,mitmdump就是使用這種事件回調的方式,為我們提供了數據流的操作方式,那首先我們要了解mitmproxy為我們提供的事件(我們只關注HTTP相關的事件)。

<code>class Events:    def request(self, flow: http.HTTPFlow):        """            The full HTTP request has been read.        """    def response(self, flow: http.HTTPFlow):        """            The full HTTP response has been read.        """/<code>

request為請求發送至服務器前的回調函數,如果我們想對發送給服務器的請求進行修改,可以在這裡進行處理。response為服務器將請求數據返回給我們時的回調函數,這裡就是我們爬取到的數據,在這裡我們可以對數據進行處理,做入庫處理。

我們在爬蟲中使用mitmproxy,主要就是對Request和Response對象進行操作,下面我在源碼中把對應的屬性和方法都找出來,作為參考,就當作是字典一樣來查詢即可。源碼在GitHub上下載,路徑為:mitmproxy/net/http/request.py和mitmproxy/net/http/response.py。

Request

<code>flow.request.cookies       #獲取請求的cookiesflow.request.headers      # 獲取所有頭信息,包含Host、User-Agent、Content-type等字段flow.request.url               # 完整的請求地址,包含域名及請求參數,但是不包含放在body裡面的請求參數flow.request.host             # 域名flow.request.method        # 請求方式。POST、GET等flow.request.scheme        # 請求類型 ,如 http、httpsflow.request.path             # 請求的路徑,url除域名之外的內容flow.request.text              # 請求中body內容,可以獲取某些請求的參數,返回字典類型flow.request.replace()      # 使用正則替換content中的內容flow.request.query           # 返回MultiDictView類型的數據,url直接帶的鍵值參數,一般是GET請求的參數flow.request.content        # bytes,結果如flow.request.textflow.request.raw_content      # bytes,結果如flow.request.get_content()flow.request.urlencoded_form  # MultiDictView,content-type:application/x-www-form-urlencoded 時的請求參數,不包含url直接帶的鍵值參數flow.request.multipart_form   # MultiDictView,content-type:multipart/form-data 時的請求參數,不包含url直接帶的鍵值參數/<code> 

Response

<code>flow.response.status_code  # 狀態碼flow.response.text            # 返回內容,已解碼flow.response.content      # 返回內容,二進制flow.response.cookies     # 返回的cookiesflow.response.headers    # 返回的請求頭flow.response.replace()      # 使用正則替換content中的內容/<code>

要特別注意,返回值為字典的類型的,不能直接在控制檯打印,可以使用str修飾,或者按照字典方式進行輸出。

以下為測試示例:

  • 測試代碼
<code>from mitmproxy import httpclass Demo1:    def request(self, flow: http.HTTPFlow):        print('request url', flow.request.url)        print('request name', flow.request.query.get('name'))        print('request age', flow.request.query.get('age'))        flow.request.query['name'] = 'yuehan'class Demo2:    def response(self, flow: http.HTTPFlow):        print('response name', flow.request.query.get('name'))addons = [    Demo1(),    Demo2()]/<code>
  • 請求url:https://httpbin.org/get?name=jieke&age=23
  • 輸出結果:
APP系列爬蟲2-mitmproxy安裝與簡介

示例中使用兩個類Demo1、Demo2,主要是為大家展示類方式的好處,即可以使用多個類,每個類處理進行獨立的邏輯處理,每個類當中都可以同時使用request、response函數,希望不要因為例子裡面而誤導了大家。下面再說一點進階用法,每一個處理類,都可以單獨寫一個py文件,再統一定義一個py文件,導入處理類,定義一個列表變量addons,變量中存儲所有處理類的實例,示例如下:demo1.py

<code>from mitmproxy import httpclass Demo1:    def request(self, flow: http.HTTPFlow):        print('request url', flow.request.url)        print('request name', flow.request.query.get('name'))        print('request age', flow.request.query.get('age'))        flow.request.query['name'] = 'yuehan'/<code>

demo2.py

<code>from mitmproxy import httpclass Demo2:    def response(self, flow: http.HTTPFlow):        print('response name', flow.request.query.get('name'))/<code>

spider.py

<code>import demo1import demo2addons = [    demo1.Demo1(),    demo2.Demo2()]/<code>
  • 抓包命令
    mitmdump -p 8888 -s spider.py

參考文章:

1.使用 mitmproxy + python 做攔截代理 https://blog.wolfogre.com/posts/usage-of-mitmproxy/

2.如何突破網站對selenium的屏蔽 https://blog.csdn.net/qq_26877377/article/details/83307208


分享到:


相關文章: