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… (二维码自动识别)