目录:
每篇前言:
- 🏆🏆作者介绍:【孤寒者】—CSDN全栈领域优质创作者、HDZ核心组成员、华为云享专家Python全栈领域博主、CSDN原力计划作者
- 🔥🔥本文已同时收录于:《Python全栈系列教程》和《爬虫从入门到精通系列教程》两个专栏
- 🔥🔥热门专栏推荐:《Django框架从入门到实战》、《爬虫从入门到精通系列教程》、《爬虫高级》、《前端系列教程》、《tornado一条龙+一个完整版项目》。
- 📝📝本专栏面向广大程序猿,为的是大家都做到Python从入门到精通,同时穿插有很多很多习题,巩固学习。
- 🎉🎉订阅专栏后****可私聊进一千多人Python全栈交流群(手把手教学,问题解答);进群可领取Python全栈教程视频 + 多得数不过来的计算机书籍:基础、Web、爬虫、数据分析、可视化、机器学习、深度学习、人工智能、算法、面试题等。
- 🚀🚀加入我一起学习进步,一个人可以走的很快,一群人才能走的更远!
一、简介和安装
mitmproxy是一个代理工具(软件安装或Python模块安装),实现代理请求(拦截请求或修改请求)。
Python爬虫用,以模块形式安装更适合我们【注意:python 版本>=3.6】:
pip install mitmproxy -i https://mirrors.aliyun.com/pypi/simple/
第一部分 - 介绍并下载安装完毕
(1)概念
Mitmproxy是一个免费的开源交互式的HTTPS代理。MITM即中间人攻击(Man-in-the-Middle Attack)。
(2)作用
- 代理的作用,转发请求,保障服务端与客户端的通信;
- 查看,记录,修改数据,引发服务端或客户端的特定行为。
(3)图解原理
(4)mitmproxy工具介绍
安装成功后在Python安装路径Script路径下可以找到 mitmdump.exemitmproxy.exemitmweb.exe 这三个可执行文件。
- mitmproxy:命令行界面,允许交互式检查和修改http数据流。不支持windows;
- mitmweb: Web界面,用户可以实时看到发生的请求,过滤请求,查看请求数据;
- mitmdump: 一个命令行工具,没有界面,不能交互,但是可以通过启动参数并结合自定义脚本进行定制化功能的实现,咱就用这个。
这三个命令功能一致,且都可以加载自定义脚本,唯一的区别是交互界面的不同;mitmproxy,mitmweb主要用来做调试,部署项目时,使用mitmdump。
第二部分 - 配置并使用
(1)设置代理
PC端设置代理:
开启代理时需要把其他的代理都关掉!
开启代理:注意现在还没有安装证书,所以https的请求是无法获取的!
PC端安装证书:获取https请求
第一种获取证书的方式:
- 运行mitmweb工具:终端命令mitweb即可。
- 在代理状态下,访问
mitm.it
,PC端与移动端操作相同。
第二种获取证书的方式:
还可以直接找到本地的证书,然后安装:
编写一个脚本,启动mitmproxy:
mitmdump -q -p 8888-s v1.py
#! python# -*- coding: utf-8 -*-# @Time : 2024/10/10 66:66# @Author : GuHanZhe# @File : baidu_crawler.pyfrom mitmproxy import http
from mitmproxy.http import HTTPFlow
defrequest(flow: http.HTTPFlow):print("请求->", flow.request.path)defresponse(flow: http.HTTPFlow):pass
在电脑
C:\Users\Administrator\.mitmproxy
中去获取。
移动端安装证书:获取https请求
(2)使用
此时我们的mitmproxy已经可以正常获取所有http以及https的请求了~
二、mitmdump的使用
其实,在我们下面的使用中会发现,mitmproxy功能跟fiddler几乎一模一样,我们为何来使用它呢?
通过下面对插件的使用,以及对插件的编写会发现,这个工具十分灵活,我们可以根据自己所需抓取想要的数据,也可以根据所需修改我们获取的响应,灵活多变!!!
(1)插件使用:
- 插件的本质就是一个脚本文件,在Python中就是一个类的实例对象。
- 此处插件是
Counter
实例对象,request
方法是一个事件 - 对于
request
事件,它的参数是一个mitmproxy.http.HTTPFlow
的对象。 上面是一个简单的插件,用于跟踪我们已经看到的流(或更具体的HTTP请求)数量。每次看到新的流量时,它都会使用mitmproxy的内部日志记录机制来进行提示。可以在交互式工具的事件日志中或mitmdump的控制台中找到输出。
比如:pycharm编写此脚本文件,Terminal中使用命令
mitmdump -s ./anatomy.py
运行插件。(./anatomy.py为此脚本文件的路径),即可在Terminal中观察到类似于下面的输出(因为使用的是mitmproxy的内部日志记录机制,所以会有很多记录数据):
小拓展:安静模式——使用命令mitmdump -q -s ./anatomy.py命令运行插件,即可屏蔽所有mitmproxy的日志信息,(注意:在request()函数中加入需要打印的信息!)输出格式如下:
#! python# -*- coding: utf-8 -*-# @Time : 2024/10/10 66:66# @Author : GuHanZhe# @File : anatomy.py"""
Basic skeleton of a mitmproxy addon.
Run as follows: mitmproxy -s anatomy.py
"""from mitmproxy import ctx
classCounter:def__init__(self):
self.num =0defrequest(self, flow):
self.num = self.num +1
ctx.log.info("We've seen %d flows"% self.num)# 需要打印的信息!print("We've seen %d flows"% self.num)
addons =[
Counter()]
上面使用的是官方给的插件例子,需要将事件放入类中进行运行。但是,如果我们只需要编写单一功能的插件,比如上面的只获取请求数量的插件,可以不那么麻烦编写——直接编写事件函数即可!(注意:事件函数名一定不能变!!!)
#! python# -*- coding: utf-8 -*-# @Time : 2024/10/10 66:66# @Author : GuHanZhe# @File : anatomy.pyfrom mitmproxy import ctx
# 事件函数
num =0defrequest(flow):global num
num +=1print('简单方法获取访问次数:', num)# 打印请求的urlprint(flow.request.url)
ctx.log.info("We've seen %d flows"% num)
(2)HTTP事件
常用事件:
①request事件:
- 查看:
#! python# -*- coding: utf-8 -*-# @Time : 2024/10/10 66:66# @Author : GuHanZhe# @File : anatomy.pydefrequest(flow):print('请求头:', flow.request.headers)print('请求url:', flow.request.url)print('域名:', flow.request.host)# 请求路径:url除域名之外的内容print('请求路径:', flow.request.path)# 返回MultiDictView类型的数据,URL的键值参数print('请求参数:', flow.request.query)print('请求方法:', flow.request.method)print('请求协议/类型(http/https):', flow.request.scheme)# 获取请求内容print('请求内容:', flow.request.get_text)print('内容类型:',type(flow.request.get_text))print('获取内容:', flow.request.get_text())print('请求内容bytes:', flow.request.raw_content)print('请求内容bytes:', flow.request.get_content())print('请求内容类型:',type(flow.request.get_content()))# 输出: <class 'bytes'>print('==========================', end='\n')
- 修改请求中的参数:
#! python# -*- coding: utf-8 -*-# @Time : 2024/10/10 66:66# @Author : GuHanZhe# @File : anatomy.pydefrequest(flow):if'https://www.baidu.com'in flow.request.url:print('需要修改的参数:', flow.request.query.get('wd'))# .set_all()方法设置请求参数
flow.request.query.set_all('wd',['爬虫'])print('修改后的参数:', flow.request.query.get('wd'))
观察百度搜索,其中搜索内容的参数是:wd。
客户端浏览器中百度中不管搜索什么,经过此mitmproxy操作,都会将搜索内容改为“爬虫”!服务端收到的请求就是——百度搜索爬虫!!!
输出:
需要修改的参数: 猫咪图片
修改后的参数: 爬虫
- 拦截请求: 拦截的形式,可以是kill当前请求:
#! python# -*- coding: utf-8 -*-# @Time : 2024/10/10 66:66# @Author : GuHanZhe# @File : baidu_crawler.pyfrom mitmproxy import http
from mitmproxy.http import HTTPFlow
defrequest(flow: HTTPFlow):if flow.request.url.startswith("https://dig.chouti.com/"):
flow.kill()defresponse(flow: http.HTTPFlow):pass
②response事件:
- 查看:
#! python# -*- coding: utf-8 -*-# @Time : 2024/10/10 66:66# @Author : GuHanZhe# @File : anatomy.pydefresponse(flow):# 状态码print(flow.response.status_code)# 返回内容,已解码print(flow.response.text)# 返回内容,Bytes类型print(flow.response.content)# 取得响应的文本print(flow.response.get_text())
- 修改响应内容:
#! python# -*- coding: utf-8 -*-# @Time : 2024/10/10 66:66# @Author : GuHanZhe# @File : anatomy.pydefresponse(flow):print('======执行修改操作======')
flow.response.set_text('信息已经被修改!')
此时不管你访问哪个网站,浏览器给你的响应都只要这一句话——信息已经被修改!
三、实战 - 下载百度图片
#! python# -*- coding: utf-8 -*-# @Time : 2024/10/10 66:66# @Author : GuHanZhe# @File : baidu_crawler.pyimport os
index =0defresponse(flow):global index
print('===========开始执行===========')if'JPEG'in flow.request.url:# 存放图片的文件夹
file_one ='image'ifnot os.path.exists(file_one):
os.mkdir(file_one)
file_name = file_one +'/'+str(index)+'.jpg'withopen(file_name,'wb')as f:
f.write(flow.response.get_content())print(index)
index +=1
Terminal终端中运行之后,百度图片中搜索一类图片(比如:猫咪图片),会发现浏览器加载图片速度稍微慢了一点点,其实,这就是我们编写的脚本代理在客户端和服务端中间截取数据,下载图片!!!
版权归原作者 孤寒者 所有, 如有侵权,请联系我们删除。