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

我们通常使用的抓包工具就是Fiddler和Charles这种图形化的,Charles的优点是跨平台,Windows和Mac都可以使用,Fiddler的优点是功能“极其”] ^ - H强大,不仅拥C F 4 4 Y Y )有抓包功能,还拥有中间人攻击的功能,但是使用成本太高了,我们做爬虫? { H a j O d R开发,使用到Fiddler的功能不过十之二三罢了。今天我们主8 X ; b e O要讲的是mitmproxy这款工具,这是一款专业的中间人攻击工具,mitmproxy 不仅可以截获请求帮m n 6 Q H U S 6助开发者查看、分析,最最重要的是支持E - w e N ~ f u ^Python进行定制化二次开发。例如:截获浏览器的请求内容,并将Z d 9 R ` b ^ =数据处理后存储到数据库,再将内容交给浏览器;如果出现异常时,发出邮件通知,并返回给浏览器一个空的页面。mitmproxy有以下几个特点:

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

安装mia - tmproxy

pip install miw # C L * . ]tmproxy

在Python环境中安装使用pip最为简洁。mitm6 } A _ & Y 4 %proxy安装完成以后会包含三个工具:mitmproxymitmdumpmitmweb。安装完成以后直t H l { a ; 7 f接在控制台输入mitmproxy --version就可以查看版本信息。

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

查看版本信息

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

Error: mitX v @ 1mproxy\'s cg ? 7 sonsole interface is not supported on Windows. You can run mitmdump orZ G f E G + B  N mitmweb instead.

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

安装浏览器代理插件SwitchyOmega

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

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

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

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

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

安装证书

正常情况下,mitmproxy启动后,} l J _ y - s W只能抓取到HTTP请求的% c r信息,我们要抓取HTTPS请求e ! * & o Z 3 =信息需要安装证书。证书安装有两种方式:

第一种

  • 首先打M ) a PF E S 6 z ymitmproxy进行抓包K G N x ; $ S 3 z即运行: mitmproxy或者另外两个命令
  • 访问http://mitm.it/

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

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

上面这种方法L ~ l = t 2 6 + )我一直访问不到mitm.i& E 2 I ^t这个页面,可以采用以下方式进行安装

第二种

  • 首先打开mitmpr$ w X u 2 _ L / Goxy进行抓包,即运行: mitmproxy或者另外两个命令。执行了这一步以后,在操作系统对应的用户名目录下会产生一个.mitmprJ D ? e w $ [ `oxy目录
APP系列爬虫2-mitmproxy安装与简介

.cer是Mac或LinuV 7 X * Q qx下的证书6 a _ _,.pT 3 R D W , f r12是Windows下的证书,.pem是安x r Z h卓下的s Z wA ( W ; - b A书。

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

使用mitmproxy

要启动 mitmproxy 用 mitmproxy、mitmdump、mitmweb 这三个命令中的任意4 y C 5 ( $ 4一个即可,这三个命令功能一致,且都可) P N M以加载自定义 Y 4脚本,唯一的区别是交互界面的不同。但是他们各有特点,mitmproxy是进行抓包调` s ?试使用的,mitmweb是miK N L : t v [ c Mtmproxy的可视版本,mitmdump主要是加载脚本执行的,因为mitmdump抓取的信息是不主动显示的,由我们在脚本中使用特定打S 7 . x印方式,输出到界面,方便我们调X X ` x H E试,当然也可以直接使用print打印。

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

from mitmproxy import http
from mitme O : b } a J 1proxy import ctx

def reM Z W F !sponse(flow: http.HTTPFlow):
\"_ Y / \"\"
flow为参数,后面跟http.HTTPFlow表示声明其类型,
这样在IDE中就可以自动提示其属性和方法,这是Python为我们提供的一种
便携的方式,尤其是{ J - ~ S D $对外提供接口时,可以s J 1 - (告知参数类型,这种方式是可选
的,当然你也可以使用常用方式,即不知道参数类型,只写参数名即可
\"4 ! t K D M Q\"\"
ctx.log.info(flow.request.url)
ctx.log.warn(flow.request.headers)

mitmproxy.ctx.log为mitmproxy为我们提供的日志P P P g k - L打印方式。

from mitmproxy import ht^ q 6 e 9 Dtp

class Counter:
def __init__(self):
self.num = 0

def reque1 b z W ` J ( 4st(self, flow: http.HTT+ j kPFlow):
self.num += 1
print(\"We\'ve seen %d flows\" % self.num)
print(flow.request.url)
print(fl` F 7 C %ow.reqC ? wuest.query)


addons = [
Counter()
]

官方推荐使用类的方式,上面的代码可能让你有点迷茫,无论是使用类方式还是函数方式def reqeust函数都是在mi) * f f @ #tmdump内部回调时会调用的,mitmdump就是使用这种事件回调的方式,为我们提供T 6 & I | U #了数据流的操作方式,那首先我们要了解mitT @ 9 y N ;mproxy为我们提供的事件(我们只关注HTTP相关的事件)。

class Events:
def reques, [ = t 7 B St(s~ D j 3 ~ Kelf, flow: http.HTTPFlow):
\"\"\X T H e z"
The full HTTP requesN R vt has been read.
\"\Y l W ; ) E a 5"\"

def response(self, flow: httpC , n w Q q . }.HTTPFlow):
\N Q A l $ ` H"\"\"
The full HX * n H L 5TTP responseh A 0 | K { - w has been read.
\"\"\"

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

我们在爬虫中使用mitmproxy,主要就是对Request和Response对象进行操作,下面我在源码中把对应的属性和方法都找^ % k f O b出来,作为参考Z 0 $ W a 5 E 5,就当作是字典一样来查询即+ E ) = . E g j可。源t _ w b h码在GitHub上下载Q ) v 8 s x c S q,路径为:mitmproxy/net/http/request.py和mitmproxy/net/http/response.py。

Request

flow.request.cookies       #r M z获取请求的cookies
flow.request.headers # 获取所有头信息,包含Host、User-Agent、Content-type等字段
flow.request.url # 完整的请求地址,y 9 Z T E l 7 d包含域名及请求参q i I %数,但是不包含放在body里面的请求参数
flow.request.host # 域名
flow.requestT 0 | : Q.method # 请求方式。POST、GET等
flow.request.scheme # 请求类型 ,如 http、https
flow.request.path # 请求的路径,url除域名之外的内容
flow.request.teP G ( ~ [ U bxt # 请求中bodO G g ~y内容,可以获取某些请求的参数,返回字典类型
flow.request.replace()O : $ w s # 使用正则替换content中的内容
flow.request.query # 返回MultiDictView类型的数据,url直接带的键值参数,一般是GET请求的{ o q参数
flow.request.content # bytes,结果如flou B | + 7 # & u ;w.request.text
flow.request.raw_content # bytes,结果如flow.requy l Test.get_content()
flow.request.urlencoded_form # MultiX L O { x | #DictView,content-type:ao ( - r ( & 3 F ]pplication/x-www-foI v ^ ` V Crm-urlencoded 时的请求参数,不包含url直接带的键值参数
fz d b y : { P Xlow.request.multipart_form # MultiDictView,contentW l 4-type:mu V x ~ltipart/q L p s mform-data 时的请求参数,不包含url直接带的键值参数

Response

flow.response.status_code  # 状态码
flow.response.text # 返回内容,已解码
flow.response.content # 返回内容,二进制
flow.response.cookies # 返回的cookies
flow.reJ 4 /sponse.headers # 返回的请求头
flow.response.repi d 3 C E 2 x 3lace() # 使用正则替换content中的内容

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

以下为测试示例:

  • 测试代码
from mitmproxy import http


class Demo1:
def request(self, flow: htj , , T $ 8tp.HTTPFlow):
print(\'requu o Q dest url\', flow.request.url)
print(\'request nameV ^ 4 d\', flow.request.query.get(\'name\'))
printD , j(\'reqs W 1 ? / |uest age\', flow.request.query.get(\'age\'))
flow.request.query[\'name\'] = \d a ) _ s'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安装与简介

示例Z , X w v (中使 0 % Y 1 P用两个类Demo1、Demo2,主要是为大家展示类方式的好处,即可以使用多个类,每个类处理进行独立的逻辑处理,每个类当中都可以同时使用request、reo n Usponse函数,希望不要因为例子里面而误* ` G导了大家。下面再说一点进阶用法,每一个处理类,都可以单独~ 9 y r ( w写一个py文件,再统一j { V o定义一个py文件,导入处理类,定义一个列表变量addons,变量中存储所有处理类的实例,示例如下:demo1.py

from mitmproxy import http

class Demo1:
def request(self, flow: http.HTTPF8 E 1 % ?low):
print(\'request url\', flow: Z a.request.url)
print(\'request name\', flow.request.query.get(\'name\'))
print(\'request ageq 5 } D U 0 B M\', flow.request.query.get(\'age\')3 [ Y M j 6)
flow.request.query[\'name\'] = \'yuehan\'

demo2.z 1 b C ) Qpy

from mitmproxy import http

class DemU ~ + | ko2:
def response(self, flow: httpi 2 g R 4 B + _.HTTPFlow):
print(\'response name\', flow.req] * ] Uuest.query.get(\'name\'))

sk P 1 e G K Zpider.py

import demo1
import demo2

addons = [
demo1.Demo1(),
demo2.Demo2()
]
  • 抓包命令
    mitmdump -p 8888 -s spide! 3 R 9r.py

参考文章:

1.使用 mit~ 9 Bmproxy + python 做拦截代理 https://blo~ : xg.wolfogre.com/posts/usage-of-mitmpr% 6 $oxy/

2.如何突破网站对seleQ A ?nium的屏蔽 https://blog.csdn.net/qq_26877377/articlw ( 8 S We/details/83307208

下一篇

“停课不停学” 我县家长提前做好线上听课准备

你也可能喜欢

  • 暂无相关文章!

发表评论

您的电子邮件地址不会被公开。 必填项已用 * 标注

提示:点击验证后方可评论!

插入图片
返回顶部