mitmproxy是一個支持HTTP和HTTPS的抓包程序,有相似Fiddler、Charles的功能,只不過它是一個控制檯的形式操做。
html
mitmproxy還有兩個關聯組件。一個是mitmdump,它是mitmproxy的命令行接口,利用它咱們能夠對接Python腳本,用Python實現監聽後的處理。另外一個是mitmweb,它是一個Web程序,經過它咱們能夠清楚觀察mitmproxy捕獲的請求。web
下面咱們來了解它們的用法。數據庫
請確保已經正確安裝好了mitmproxy,而且手機和PC處於同一個局域網下,同時配置好了mitmproxy的CA證書。
api
mitmproxy有以下幾項功能。
瀏覽器
攔截HTTP和HTTPS請求和響應。安全
保存HTTP會話並進行分析。bash
模擬客戶端發起請求,模擬服務端返回響應。服務器
利用反向代理將流量轉發給指定的服務器。微信
支持Mac和Linux上的透明代理。cookie
利用Python對HTTP請求和響應進行實時處理。
和Charles同樣,mitmproxy運行於本身的PC上,mitmproxy會在PC的8080端口運行,而後開啓一個代理服務,這個服務其實是一個HTTP/HTTPS的代理。
手機和PC在同一個局域網內,設置代理爲mitmproxy的代理地址,這樣手機在訪問互聯網的時候流量數據包就會流經mitmproxy,mitmproxy再去轉發這些數據包到真實的服務器,服務器返回數據包時再由mitmproxy轉發回手機,這樣mitmproxy就至關於起了中間人的做用,抓取到全部Request和Response,另外這個過程還能夠對接mitmdump,抓取到的Request和Response的具體內容均可以直接用Python來處理,好比獲得Response以後咱們能夠直接進行解析,而後存入數據庫,這樣就完成了數據的解析和存儲過程。
首先,咱們須要運行mitmproxy,命令以下所示:
啓動mitmproxy的命令以下:
mitmproxy複製代碼
以後會在8080端口上運行一個代理服務,以下圖所示。
右下角會出現當前正在監聽的端口。
或者啓動mitmdump,它也會監聽8080端口,命令以下所示:
mitmdump複製代碼
運行結果以下圖所示。
將手機和PC鏈接在同一局域網下,設置代理爲當前代理。首先看看PC的當前局域網IP。
Windows上的命令以下所示:
ipconfig複製代碼
Linux和Mac上的命令以下所示:
ifconfig複製代碼
輸出結果以下圖所示。
通常相似10.*.*.*或172.16.*.*或192.168.1.*這樣的IP就是當前PC的局域網IP,例如此圖中PC的IP爲192.168.1.28,手機代理設置相似以下圖所示。
這樣咱們就配置好了mitmproxy的的代理。
確保mitmproxy正常運行,而且手機和PC處於同一個局域網內,設置了mitmproxy的代理,具體的配置方法能夠參考官方文檔。
運行mitmproxy,命令以下所示:
mitmproxy複製代碼
設置成功以後,咱們只須要在手機瀏覽器上訪問任意的網頁或瀏覽任意的App便可。例如在手機上打開百度,mitmproxy頁面便會呈現出手機上的全部請求,以下圖所示。
這就至關於以前咱們在瀏覽器開發者工具監聽到的瀏覽器請求,在這裏咱們藉助於mitmproxy完成。Charles徹底也能夠作到。
這裏是剛纔手機打開百度頁面時的全部請求列表,左下角顯示的2/38表明一共發生了38個請求,當前箭頭所指的是第二個請求。
每一個請求開頭都有一個GET或POST,這是各個請求的請求方式。緊接的是請求的URL。第二行開頭的數字就是請求對應的響應狀態碼,後面是響應內容的類型,如text/html表明網頁文檔、image/gif表明圖片。再日後是響應體的大小和響應的時間。
當前呈現了全部請求和響應的概覽,咱們能夠經過這個頁面觀察到全部的請求。
若是想查看某個請求的詳情,咱們能夠敲擊回車,進入請求的詳情頁面,以下圖所示。
能夠看到Headers的詳細信息,如Host、Cookies、User-Agent等。
最上方是一個Request、Response、Detail的列表,當前處在Request這個選項上。這時咱們再點擊TAB鍵,便可查看這個請求對應的響應詳情,以下圖所示。
最上面是響應頭的信息,下拉以後咱們能夠看到響應體的信息。針對當前請求,響應體就是網頁的源代碼。
這時再敲擊TAB鍵,切換到最後一個選項卡Detail,便可看到當前請求的詳細信息,如服務器的IP和端口、HTTP協議版本、客戶端的IP和端口等,以下圖所示。
mitmproxy還提供了命令行式的編輯功能,咱們能夠在此頁面中從新編輯請求。敲擊e鍵便可進入編輯功能,這時它會詢問你要編輯哪部份內容,如Cookies、Query、URL等,每一個選項的第一個字母會高亮顯示。敲擊要編輯內容名稱的首字母便可進入該內容的編輯頁面,如敲擊m便可編輯請求的方式,敲擊q便可修改GET請求參數Query。
這時咱們敲擊q,進入到編輯Query的頁面。因爲沒有任何參數,咱們能夠敲擊a來增長一行,而後就能夠輸入參數對應的Key和Value,以下圖所示。
這裏咱們輸入Key爲wd,Value爲NBA。
而後再敲擊esc鍵和q鍵,返回以前的頁面,再敲擊e和p鍵修改Path。和上面同樣,敲擊a增長Path的內容,這時咱們將Path修改成s,以下圖所示。
再敲擊esc和q鍵返回,這時咱們能夠看到最上面的請求連接變成了:https://www.baidu.com/s?wd=NBA。訪問這個頁面,能夠看到百度搜索NBA關鍵詞的搜索結果,以下圖所示。
敲擊a保存修改,敲擊r從新發起修改後的請求,便可看到上方請求方式前面多了一個迴旋箭頭,這說明從新執行了修改後的請求。這時咱們再觀察響應體內容,便可看到搜索NBA的頁面結果的源代碼,以下圖所示。
以上內容即是mitmproxy的簡單用法。利用mitmproxy,咱們能夠觀察到手機上的全部請求,還能夠對請求進行修改並從新發起。
Fiddler、Charles也有這個功能,並且它們的圖形界面操做更加方便。那麼mitmproxy的優點何在?
mitmproxy的強大之處體如今它的另外一個工具mitmdump,有了它咱們能夠直接對接Python對請求進行處理。下面咱們來看看mitmdump的用法。
mitmdump是mitmproxy的命令行接口,同時還能夠對接Python對請求進行處理,這是相比Fiddler、Charles等工具更加方便的地方。有了它咱們能夠不用手動截獲和分析HTTP請求和響應,只需寫好請求和響應的處理邏輯便可。它還能夠實現數據的解析、存儲等工做,這些過程均可以經過Python實現。
咱們可使用命令啓動mitmproxy,並把截獲的數據保存到文件中,命令以下所示:
mitmdump -w outfile複製代碼
其中outfile
的名稱任意,截獲的數據都會被保存到此文件中。
還能夠指定一個腳原本處理截獲的數據,使用-s
參數便可:
mitmdump -s script.py複製代碼
這裏指定了當前處理腳本爲script.py,它須要放置在當前命令執行的目錄下。
咱們能夠在腳本里寫入以下的代碼:
def request(flow):
flow.request.headers['User-Agent'] = 'MitmProxy'
print(flow.request.headers)複製代碼
咱們定義了一個request()
方法,參數爲flow
,它實際上是一個HTTPFlow
對象,經過request
屬性便可獲取到當前請求對象。而後打印輸出了請求的請求頭,將請求頭的User-Agent修改爲了MitmProxy。
運行以後咱們在手機端訪問http://httpbin.org/get,能夠看到以下狀況發生。
手機端的頁面顯示以下圖所示。
PC端控制檯輸出以下圖所示。
手機端返回結果的Headers實際上就是請求的Headers,User-Agent被修改爲了mitmproxy。PC端控制檯輸出了修改後的Headers內容,其User-Agent的內容正是mitmproxy。
因此,經過這三行代碼咱們就能夠完成對請求的改寫。print()
方法輸出結果能夠呈如今PC端控制檯上,能夠方便地進行調試。
mitmdump提供了專門的日誌輸出功能,能夠設定不一樣級別以不一樣顏色輸出結果。咱們把腳本修改爲以下內容:
from mitmproxy import ctx
def request(flow):
flow.request.headers['User-Agent'] = 'MitmProxy'
ctx.log.info(str(flow.request.headers))
ctx.log.warn(str(flow.request.headers))
ctx.log.error(str(flow.request.headers))複製代碼
這裏調用了ctx模塊,它有一個log功能,調用不一樣的輸出方法就能夠輸出不一樣顏色的結果,以方便咱們作調試。例如,info()
方法輸出的內容是白色的,warn()
方法輸出的內容是黃色的,error()
方法輸出的內容是紅色的。運行結果以下圖所示。
不一樣的顏色對應不一樣級別的輸出,咱們能夠將不一樣的結果合理劃分級別輸出,以更直觀方便地查看調試信息。
最開始咱們實現了request()
方法而且對Headers進行了修改。下面咱們來看看Request還有哪些經常使用的功能。咱們先用一個實例來感覺一下。
from mitmproxy import ctx
def request(flow):
request = flow.request
info = ctx.log.info
info(request.url)
info(str(request.headers))
info(str(request.cookies))
info(request.host)
info(request.method)
info(str(request.port))
info(request.scheme)複製代碼
咱們修改腳本,而後在手機上打開百度,便可看到PC端控制檯輸出了一系列的請求,在這裏咱們找到第一個請求。控制檯打印輸出了Request的一些常見屬性,如URL、Headers、Cookies、Host、Method、Scheme等。輸出結果以下圖所示。
結果中分別輸出了請求連接、請求頭、請求Cookies、請求Host、請求方法、請求端口、請求協議這些內容。
同時咱們還能夠對任意屬性進行修改,就像最初修改Headers同樣,直接賦值便可。例如,這裏將請求的URL修改一下,腳本修改以下所示:
def request(flow):
url = 'https://httpbin.org/get'
flow.request.url = url複製代碼
手機端獲得以下結果,以下圖所示。
比較有意思的是,瀏覽器最上方仍是呈現百度的URL,可是頁面已經變成了httpbin.org的頁面了。另外,Cookies明顯仍是百度的Cookies。咱們只是用簡單的腳本就成功把請求修改成其餘的站點。經過這種方式修改和僞造請求就變得垂手可得。
經過這個實例咱們知道,有時候URL雖然是正確的,可是內容並不是是正確的。咱們須要進一步提升本身的安全防範意識。
Request還有不少屬性,在此再也不一一列舉。更多屬性能夠參考:http://docs.mitmproxy.org/en/latest/scripting/api.html。
只要咱們瞭解了基本用法,會很容易地獲取和修改Reqeust的任意內容,好比能夠用修改Cookies、添加代理等方式來規避反爬。
對於爬蟲來講,咱們更加關心的實際上是Response的內容,由於Response Body纔是爬取的結果。對於Response來講,mitmdump也提供了對應的處理接口,就是response()
方法。下面咱們用一個實例感覺一下。
from mitmproxy import ctx
def response(flow):
response = flow.response
info = ctx.log.info
info(str(response.status_code))
info(str(response.headers))
info(str(response.cookies))
info(str(response.text))複製代碼
將腳本修改成如上內容,而後手機訪問:http://httpbin.org/get。
這裏打印輸出了Response的status_code
、headers
、cookies
、text
這幾個屬性,其中最主要的text
屬性就是網頁的源代碼。
PC端控制檯輸出以下圖所示。
控制檯輸出了Response的狀態碼、響應頭、Cookies、響應體這幾部份內容。
咱們能夠經過response()
方法獲取每一個請求的響應內容。接下來再進行響應的信息提取和存儲,咱們就能夠成功完成爬取了。
本資源首發於崔慶才的我的博客靜覓: Python3網絡爬蟲開發實戰教程 | 靜覓
如想了解更多爬蟲資訊,請關注個人我的微信公衆號:進擊的Coder
weixin.qq.com/r/5zsjOyvEZ… (二維碼自動識別)