python爬虫Mitmproxy安装使用 python爬虫Mitmproxy安装使用学习笔记
别呀 人气:0一、简介和安装
1.1、概念和作用
概念
Mitmproxy是一个免费的开源交互式的HTTPS代理。MITM即中间人攻击(Man-in-the-Middle Attack)。
作用
代理的作用,转发请求,保障服务端与客户端的通信
查看,记录,修改数据,引发服务端或客户端的特定行为
补充:Mitmproxy与Fiddler、Charles异同
相同点: a、都是用来捕获 HTTP,HTTPS 请求的(其他协议比如 TCP,UDP,IP,ICMP 等就用Wireshark)
b、抓包、断点调试、请求替换、构造请求、模拟弱网等
不同点:a、Fiddler只能运行在Windows系统;Mitmproxy、Charles是跨平台的,可运行在Windows、Mac或Linux系统等。
b、Fiddler、Mitmproxy开源免费、Charles是收费的(可破解)。
c、Mitmproxy支持命令行交互模式、GUI界面,Fiddler、Charles仅支持GUI界面
(Fiddler底部有个命令行工具叫做 QuickExec)
1.2、安装
pip install mitmproxy
或
pip install -i http://pypi.douban.com/simple mitmproxy
如果直接安装的速度太慢了,可以在命令行中添加国内的镜像源加快速度,就是第二条命令。注意:python 版本不低于3.6
检查是否安装成功:命令行中输入命令查看mitmdump --version
安装成功后在Python安装路径Script路径下可以找到 mitmdump.exe
、mitmproxy.exe
、mitmweb.exe
这三个可执行文件。
1.3、工具介绍
mitmproxy
:命令行界面,允许交互式检查和修改http数据流,不支持windows
mitmweb
: Web界面,用户可以实时看到发生的请求,过滤请求,查看请求数据
mitmdump
: 一个命令行工具,没有界面,不能交互,但是可以通过启动参数并结合自定义脚本进行定制化功能的实现,是我们运行的环境
这三个命令功能一致,且都可以加载自定义脚本,唯一的区别是交互界面的不同;
mitmproxy,mitmweb主要用来做调试,部署项目时使用mitmdump。
二、设置代理
2.1、PC端设置代理
开启代理时需要把其他的代理都关掉
注:这时我们刚开启代理,还未安装证书,如果访问其他网址会出现报错,如下图所示:
2.2、PC端安装证书
在代理状态下,访问http://mitm.it/,PC端与移动端操作相同。
(注意:设置完成后,浏览器打开网页发现都是未连接网络,需要先启动mitmweb.exe或者mitmdump.exe程序才能打开链接)
后面点击下载的证书按步骤导入就可以了
2.3、移动端设置代理
以夜神模拟器为例(注意保证手机和电脑在同局域网下)
设置完代理,打开浏览器访问http://mitm.it/
三、 mitmdump
官方文档:https://docs.mitmproxy.org/stable/addons-overview/
3.1、插件使用
- 插件的本质就是一个脚本文件,在Python中就是一个类的实例对象。
- 此处插件是
Counter
实例对象,request
方法是一个事件 - 对于
request
事件,它的参数是一个mitmproxy.http.HTTPFlow
的对象。
如:(官方文档例子)
""" Basic skeleton of a mitmproxy addon. Run as follows: mitmproxy -s anatomy.py """ from mitmproxy import ctx class Counter: def __init__(self): self.num = 0 def request(self, flow): self.num = self.num + 1 ctx.log.info("We've seen %d flows" % self.num) addons = [ Counter() ]
上面是一个简单的插件,用于跟踪我们已经看到的流(或更具体的HTTP请求)数量。每次看到新的流量时,它都会使用mitmproxy的内部日志记录机制来宣布其提示。可以在交互式工具的事件日志中或mitmdump的控制台中找到输出。
可以使用mitmdump -s ./anatomy.py
运行插件(anatomy.py是创建的文件名)。
3.2、常用事件
def request(self, flow: mitmproxy.http.HTTPFlow): """ The full HTTP request has been read. """ def response(self, flow: mitmproxy.http.HTTPFlow): """ The full HTTP response has been read. """
3.2.1、request事件
(注意:记得在代理状态下执行,命令:mitmdump -s ./xxx.py
)
from mitmproxy import http def request(flow:http.HTTPFlow): #注意函数名request不能写错 #获取请求头信息 print('请求头',flow.request.headers) #完整请求地址 print('请求url',flow.request.url) #域名 print('域名',flow.request.host) #请求路径 url除域名之外的内容 print('请求路径',flow.request.path) #返回MultiDictView类型的数据,URL的键值参数 print('url的键值参数',flow.request.query) #请求方法 print('请求方法',flow.request.method) #请求类型 print('请求类型',flow.request.scheme) #获取请求内容 ''' print('请求内容',flow.request.get_text) print('请求内容类型',type(flow.request.get_text)) print('请求内容bytes',flow.request.raw_content) print('请求内容bytes',flow.request.get_content) ''' if 'https://www.baidu.com' in flow.request.url: #取得请求参数wd的值 print(flow.request.query.get('wd')) #取得所有请求参数 print(list(flow.request.query.keys())) #修改请求参数 flow.request.query.set_all('wd',['python']) #打印修改过后的参数 print(flow.request.query.get('wd'))
3.2.2、response事件
(注意:记得在代理状态下执行,命令:mitmdump -s ./xxx.py
)
from mitmproxy import http def response(flow:http.HTTPFlow): #注意函数名response不能写错 #状态码 print('状态码',flow.response.status_code) #返回内容,已解码 print('返回内容',flow.response.text) #返回内容, bytes类型 print('返回内容bytes类型',flow.response.content) #取得响应的文本 print('应的文本',flow.response.get_text) #修改响应 的文本 flow.response.set_text('你的响应内容被修改了!')
3.3、下载图片
(注意:记得在代理状态下执行,命令:mitmdump -q -s ./xxx.py
加-q会使打印更清晰可观)
import os index = 0 def response(flow): global index print('===========下载==============') print(flow.request.url) if flow.request.url[-3:] == 'jpg': dir = 'images' if not os.path.exists(dir): os.mkdir(dir) filename = dir+'/'+str(index)+'.jpg' with open(filename,'wb') as f: f.write(flow.response.get_content()) index+=1
加载全部内容