您所在的位置: > 主页 > 安徽热线 > 娱乐 > 正文
APP系列爬虫2-mitmproxy安装与简介来源: 日期:2020-04-01 08:01:30  阅读:-

    我们通常使用的抓包工具就是Fiddler和Charles这种图形化的,Charles的优点是跨平台,Windows和Mac都可以使用,Fiddler的优点是功能“极其”强大,不仅拥有抓包功能,还拥有中间人攻击的功能,但是使用成本太高了,我们做爬虫开发,使用到Fiddler的功能不过十之二三罢了。今天我们主要讲的是mitmproxy这款工具,这是一款专业的中间人攻击工具,mitmproxy 不仅可以截获请求帮助开发者查看、分析,最最重要的是支持Python进行定制化二次开发。例如:截获浏览器的请求内容,并将数据处理后存储到数据库,再将内容交给浏览器;如果出现异常时,发出邮件通知,并返回给浏览器一个空的页面。mitmproxy有以下几个特点:

    • 像正常代理一样转发请求,保证服务器和客户端之间的通信
    • 可以拦截请求/返回,并可以修改请求/返回
    • 可以加载Python脚本执行

    安装mitmproxy

    pip install mitmproxy

    在Python环境中安装使用pip最为简洁。mitmproxy安装完成以后会包含三个工具:mitmproxymitmdumpmitmweb。安装完成以后直接在控制台输入mitmproxy --version就可以查看版本信息。

    APP系列爬虫2-mitmproxy安装与简介


    查看版本信息

    注意如果是在Windows系统中安装,需要先安装Microsoft Visual C++ V14.0以上版本,并且mitmproxy是不能在Windows系统中进行抓包的,在执行mitmproxy --version命令的时候会得到一个错误提示。

    Error: mitmproxy's console interface is not supported on Windows. You can run mitmdump or mitmweb instead.

    在Windows系统中我们主要使用的是安装完以后的另外两个工具mitmdump和mitmweb。

    安装浏览器代理插件SwitchyOmega

    为什么要先安装浏览器代理插件呢?因为我们在使用抓包工具的时候,必须要通过代理访问网络,才能抓到包,可以通过设置系统代理的方式来实现,但是直接设置浏览器代理会更加方便,而且使用代理插件我们可以配置多种代理模式。Chrome浏览器安装插件需要科学上网,只要在度娘搜索谷歌上网助手,安装以后重启浏览器,就可以访问谷歌商店来安装插件了,插件我们这里推荐SwitchyOmega。安装完以后要进行设置。

    • 打开选项
      打开设置项
    • 新建情景模式
    APP系列爬虫2-mitmproxy安装与简介

    • 设置代理地址和端口
    APP系列爬虫2-mitmproxy安装与简介

    然后在浏览器中访问地址前,先选择代理方式,再进行访问

    APP系列爬虫2-mitmproxy安装与简介

    安装证书

    正常情况下,mitmproxy启动后,只能抓取到HTTP请求的信息,我们要抓取HTTPS请求信息需要安装证书。证书安装有两种方式:

    第一种

    • 首先打开mitmproxy进行抓包,即运行: mitmproxy或者另外两个命令
    • 访问http://mitm.it/

    如果你没有打开mitmproxy进行抓包的话,在这一步你会得到如下错误

    APP系列爬虫2-mitmproxy安装与简介

    上面这种方法我一直访问不到mitm.it这个页面,可以采用以下方式进行安装

    第二种

    • 首先打开mitmproxy进行抓包,即运行: mitmproxy或者另外两个命令。执行了这一步以后,在操作系统对应的用户名目录下会产生一个.mitmproxy目录
    APP系列爬虫2-mitmproxy安装与简介

    .cer是Mac或Linux下的证书,.p12是Windows下的证书,.pem是安卓下的证书。

    通过上述两种方式得到证书文件后,证书按照步骤在网上找,非常多,这里就不再敖述了。

    使用mitmproxy

    要启动 mitmproxy 用 mitmproxy、mitmdump、mitmweb 这三个命令中的任意一个即可,这三个命令功能一致,且都可以加载自定义脚本,唯一的区别是交互界面的不同。但是他们各有特点,mitmproxy是进行抓包调试使用的,mitmweb是mitmproxy的可视版本,mitmdump主要是加载脚本执行的,因为mitmdump抓取的信息是不主动显示的,由我们在脚本中使用特定打印方式,输出到界面,方便我们调试,当然也可以直接使用print打印。

    在控制台中输入mitmdump -h,可以查看命令行帮助,我们主要使用的是-s和-p参数,-p指定监听端口,默认端口为8080,如果和其他软件有冲突,可以通过此参数修改;-s指定执行脚本,这个就是我们用mitmproxy的主要作用,通过加载脚本,执行请求过程的中间处理,修改请求数据或者保存返回数据。目前有两种使用方式:

    from mitmproxy import httpfrom mitmproxy import ctxdef response(flow: http.HTTPFlow):    """    flow为参数,后面跟http.HTTPFlow表示声明其类型,    这样在IDE中就可以自动提示其属性和方法,这是Python为我们提供的一种    便携的方式,尤其是对外提供接口时,可以告知参数类型,这种方式是可选    的,当然你也可以使用常用方式,即不知道参数类型,只写参数名即可    """    ctx.log.info(flow.request.url)    ctx.log.warn(flow.request.headers)

    mitmproxy.ctx.log为mitmproxy为我们提供的日志打印方式。

    from mitmproxy import httpclass Counter:    def __init__(self):        self.num = 0    def request(self, flow: http.HTTPFlow):        self.num += 1        print("We've seen %d flows" % self.num)        print(flow.request.url)        print(flow.request.query)addons = [    Counter()]

    官方推荐使用类的方式,上面的代码可能让你有点迷茫,无论是使用类方式还是函数方式def reqeust函数都是在mitmdump内部回调时会调用的,mitmdump就是使用这种事件回调的方式,为我们提供了数据流的操作方式,那首先我们要了解mitmproxy为我们提供的事件(我们只关注HTTP相关的事件)。

    class Events:    def request(self, flow: http.HTTPFlow):        """            The full HTTP request has been read.        """    def response(self, flow: http.HTTPFlow):        """            The full HTTP response has been read.        """

    request为请求发送至服务器前的回调函数,如果我们想对发送给服务器的请求进行修改,可以在这里进行处理。response为服务器将请求数据返回给我们时的回调函数,这里就是我们爬取到的数据,在这里我们可以对数据进行处理,做入库处理。

    我们在爬虫中使用mitmproxy,主要就是对Request和Response对象进行操作,下面我在源码中把对应的属性和方法都找出来,作为参考,就当作是字典一样来查询即可。源码在GitHub上下载,路径为:mitmproxy/net/http/request.py和mitmproxy/net/http/response.py。

    Request

    flow.request.cookies       #获取请求的cookiesflow.request.headers      # 获取所有头信息,包含Host、User-Agent、Content-type等字段flow.request.url               # 完整的请求地址,包含域名及请求参数,但是不包含放在body里面的请求参数flow.request.host             # 域名flow.request.method        # 请求方式。POST、GET等flow.request.scheme        # 请求类型 ,如 http、httpsflow.request.path             # 请求的路径,url除域名之外的内容flow.request.text              # 请求中body内容,可以获取某些请求的参数,返回字典类型flow.request.replace()      # 使用正则替换content中的内容flow.request.query           # 返回MultiDictView类型的数据,url直接带的键值参数,一般是GET请求的参数flow.request.content        # bytes,结果如flow.request.textflow.request.raw_content      # bytes,结果如flow.request.get_content()flow.request.urlencoded_form  # MultiDictView,content-type:application/x-www-form-urlencoded 时的请求参数,不包含url直接带的键值参数flow.request.multipart_form   # MultiDictView,content-type:multipart/form-data 时的请求参数,不包含url直接带的键值参数

    Response

    flow.response.status_code  # 状态码flow.response.text            # 返回内容,已解码flow.response.content      # 返回内容,二进制flow.response.cookies     # 返回的cookiesflow.response.headers    # 返回的请求头flow.response.replace()      # 使用正则替换content中的内容

    要特别注意,返回值为字典的类型的,不能直接在控制台打印,可以使用str修饰,或者按照字典方式进行输出。

    以下为测试示例:

    • 测试代码
    from mitmproxy import httpclass Demo1:    def request(self, flow: http.HTTPFlow):        print('request url', flow.request.url)        print('request name', flow.request.query.get('name'))        print('request age', flow.request.query.get('age'))        flow.request.query['name'] = 'yuehan'class Demo2:    def response(self, flow: http.HTTPFlow):        print('response name', flow.request.query.get('name'))addons = [    Demo1(),    Demo2()]
    • 请求url:https://httpbin.org/get?name=jieke&age=23
    • 输出结果:
    APP系列爬虫2-mitmproxy安装与简介

    示例中使用两个类Demo1、Demo2,主要是为大家展示类方式的好处,即可以使用多个类,每个类处理进行独立的逻辑处理,每个类当中都可以同时使用request、response函数,希望不要因为例子里面而误导了大家。下面再说一点进阶用法,每一个处理类,都可以单独写一个py文件,再统一定义一个py文件,导入处理类,定义一个列表变量addons,变量中存储所有处理类的实例,示例如下:demo1.py

    from mitmproxy import httpclass Demo1:    def request(self, flow: http.HTTPFlow):        print('request url', flow.request.url)        print('request name', flow.request.query.get('name'))        print('request age', flow.request.query.get('age'))        flow.request.query['name'] = 'yuehan'

    demo2.py

    from mitmproxy import httpclass Demo2:    def response(self, flow: http.HTTPFlow):        print('response name', flow.request.query.get('name'))

    spider.py

    import demo1import demo2addons = [    demo1.Demo1(),    demo2.Demo2()]
    • 抓包命令
      mitmdump -p 8888 -s spider.py

    参考文章:

    1.使用 mitmproxy + python 做拦截代理 https://blog.wolfogre.com/posts/usage-of-mitmproxy/

    2.如何突破网站对selenium的屏蔽 https://blog.csdn.net/qq_26877377/article/details/83307208

    (正文已结束)

    免责声明及提醒:此文内容为本网所转载企业宣传资讯,该相关信息仅为宣传及传递更多信息之目的,不代表本网站观点,文章真实性请浏览者慎重核实!任何投资加盟均有风险,提醒广大民众投资需谨慎!