mitmproxy -py腳本編寫


原文鏈接 https://blog.csdn.net/qianwenjun_19930314/article/details/88227335

1、腳本編寫的兩個條件

​ 1.1 編寫一個 py 文件供 mitmproxy 加載,文件中定義了若干函數,這些函數實現了某些 mitmproxy 提供的事件,mitmproxy 會在某個事件發生時調用對應的函數
​ 1.2 編寫一個 py 文件供 mitmproxy 加載,文件定義了【變量 addons】,addons 是個數組,每個元素是一個類實例,這些類有若干方法,這些方法實現了某些 mitmproxy 提供的事件,mitmproxy 會在某個事件發生時調用對應的方法。這些類,稱為一個個 addon。
基本模板為

from mitmproxy import http, ctx
import json

class xxx:
	def xxx:
	def xxx

addons = [
	xxx() //類名的加載,也可以定義多個類,然后以數組的形式添加,進行加載
]
 1.3 針對 HTTP 生命周期
def http_connect(self, flow: mitmproxy.http.HTTPFlow):
 

(Called when) 收到了來自客戶端的 HTTP CONNECT 請求。在 flow 上設置非 2xx 響應將返回該響應並斷開連接。CONNECT 不是常用的 HTTP 請求方法,目的是與服務器建立代理連接,僅是 client 與 proxy 的之間的交流,所以 CONNECT 請求不會觸發 request、response 等其他常規的 HTTP 事件。

def requestheaders(self, flow: mitmproxy.http.HTTPFlow):
 

(Called when) 來自客戶端的 HTTP 請求的頭部被成功讀取。此時 flow 中的 request 的 body 是空的。

def request(self, flow: mitmproxy.http.HTTPFlow):
 

(Called when) 來自客戶端的 HTTP 請求被成功完整讀取。

def responseheaders(self, flow: mitmproxy.http.HTTPFlow):
 

(Called when) 來自服務端的 HTTP 響應的頭部被成功讀取。此時 flow 中的 response 的 body 是空的。

def response(self, flow: mitmproxy.http.HTTPFlow):
 

(Called when) 來自服務端端的 HTTP 響應被成功完整讀取。

def error(self, flow: mitmproxy.http.HTTPFlow):
 

(Called when) 發生了一個 HTTP 錯誤。比如無效的服務端響應、連接斷開等。注意與“有效的 HTTP 錯誤返回”不是一回事,后者是一個正確的服務端響應,只是 HTTP code 表示錯誤而已。

2 、腳本函數編寫

​ 2.1 替換請求

from mitmproxy import ctx, http
import json

class Modify:

 	    def request(self, flow):
 	    	#替換請求鏈接
        	if flow.request.url.startswith("http://spay1.shuqireader.com/api/ios/info?method=priceList"):
            #有分享
            flow.request.url = "http://activity.x.xxx.xx.cn/share?id=2653&useShare=1"
            ctx.log.info("修改鏈接")
        		
         
addons = [
	Modify()
]

​ 2.2 修改cookies

from mitmproxy import ctx, http
import json

class Modify:

 	 def request(self, flow):
         #替換cookie,兩種匹配請求鏈接的方式
        # if flow.request.host == "xxx.x.xxx.com.cn":
        if flow.request.url.startswith("https://xxx.x.xxx.com.cn/"):
            print(flow.request.url)
            print(flow.request.cookies)
            flow.request.cookies["_testCookie1"] = "xxx-91"
            flow.request.cookies["testCookie2"] = "123"

            req = flow.request.cookies["_testCookie1"]
            ctx.log.info(req)

addons = [
	Modify()
]

​ 2.3 修改請求參數

from mitmproxy import ctx, http
import json

class Modify:
 	 def request(self, flow):
                if flow.request.url.startswith("http://xxx.x.xxx.com.cn/customActivity/bookcode/doJoin"):
            ctx.log.info("modify request form")
            if flow.request.urlencoded_form:
                flow.request.urlencoded_form["code"] = "11111"
            else:
                flow.request.urlencoded_form = [
                    ("actId", "20727"),("nick","name")
                ]
         
addons = [
	Modify()
]

​ 2.4 修改相應狀態

from mitmproxy import ctx, http
import json

class Modify:
	def response(self, flow):
		 if flow.request.url.startswith("http://baidu.com.cn"):
            flow.response = http.HTTPResponse.make(404)
            ctx.log.info("modify status code")

 addons = [
	Modify()
]

​ 2.5 修改響應體

from mitmproxy import ctx, http
import json

class Modify:
	def response(self, flow):
        if flow.request.url.startswith("https://xxx.x.xxx.com.cn/activityInfo/getPrizeInfo=="):
       		 //獲取響應的json字符串,轉成python對象進行解析和修改
            response = json.loads(flow.response.get_text())
            response['limitCount'] = 1
            //修改完成后,獎python對象轉成json字符串,set進請求的響應體重發送給客戶端
            flow.response.set_text(json.dumps(response))
            ctx.log.info('modify limitCount')

 addons = [
	Modify()
]

​ 2.6 讀取json文件中字符串返回客戶端

from mitmproxy import ctx, http
import json

class Modify:
	def response(self, flow):
        if flow.request.url.startswith("https://xxx.x.xxx.com.cn/activityInfo/getPrizeInfo=="):
        	//讀取文件,在當前文件路徑下執行腳本,否則需要寫文件的絕對路徑;不然會找不到該json文件
       		 with open('getStatus.json','rb') as f:
       		 	//從json文件中讀取數據成python對象
                res = json.load(f)
            //將讀取的python對象轉成json字符串發送給客戶端
            flow.response.set_text(json.dumps(res))
            ctx.log.info("modify order status")

 addons = [
	Modify()
]
2.7 Request的一些方法:
get_query():得到請求的url的參數,被存放成了字典。
set_query(odict):設置請求的url參數,參數是字典。 
get_url():請求的url。 set_url(url):設置# url的域。 
get_cookies():得到請求的cookie。 headers:請求的header的字典。 
content:請求的內容,如果請求時post,那么content就是指代post的參數。 
Response的一些方法如下: Headers:返回的header的字典。 
Code:返回數據包的狀態,比如200,301之類的狀態。 
Httpversion:http版本。

3、腳本加載

mitmdump -s script.py

4、插件腳本的基本使用

4.1 日志輸出,
日志輸出
調用ctx模塊:from mitmproxy import ctx引入,然后通過ctx.log.xxx輸出:
ctx.log.info(顯示白色)
ctx.log.wran(顯示黃色)
ctx.log.error(顯示紅色)
4.2 參數flow,我們可以通過flow.request屬性獲取當前請求,
通過flow.request.xxx獲取相應屬性,如:
flow.request.url(請求的url地址)
flow.request.headers(請求頭信息)
flow.request.cookies(cookies信息)
flow.request.host(host標頭值)
flow.request.method(請求方法)
flow.request.port(請求的端口)
flow.request.scheme(請求協議)
更多內容請查看mitmproxy的API接口
不僅可以獲取相應的值,我們也可以對其值進行修改:

flow.request.url = 新的url

# 通過這種方式我們就可以進行修改和偽造請求,通過此方式我們知道,在日常上網的過程中,有時候我們輸入的url是正確的,但是頁面內容卻與我們所需要看到的不同, 有的釣魚網站可能是通過此方式進行改變網頁信息的,因此我們在日常上網過程中應注意網絡安全。
# 在日常爬蟲過程中,我們可以通過修改cookies和添加代理的方式來規避網站的反爬。

4.3 參數flow,我們可以通過flow.response屬性獲取當前請求

# 對於爬蟲來說,我們更想獲取其響應的內容,對於響應來說,我們采用response()方法來獲取響應的內容:
通過flow.response.xxx獲取相應屬性,如:
flow.repsonse.status_code(獲取響應的狀態碼)
flow.repsonse.headers(獲取響應頭信息)
flow.repsonse.cookies(獲取響應的cookies信息)
flow.repsonse.text(獲取響應的內容)
通過上述的這些基本方法再加上一些數據的存儲技術,就可以實現對數據的抓取了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM