前言:
说起抓包工具,很多人肯定会第一时间想起fiddler,charles 等HTTP/HTTPS抓包工具,的确fiddler和charles确实是现在最主流的抓包工具了,也确实很好用,我也是经常用的。但是现在有些app虽然你能抓到包,请求数据里面是一些无规律的参数,这样我们如果想携带这些参数去发送请求,获取响应数据就是是一件很难的事情了,但是今天我介绍的这款抓包工具,虽然不是什么主流的工具,但是它却有一个非常厉害的功能,它可以对抓包结果通过脚本进行实时处理和保存,这样我们就可以绕过这些无规律的参数,实现抓包请求,并获取我们需要的数据了。
一、mitmproxy的安装和使用
mitmproxy和fiddler,charles一样,也是一个支持HTTP和HTTPS的抓包工具,只不过它是以控制台的形式操作的,对于使用惯了可视界面工具的我们,就需要付出一点学习成本了。
安装mitmproxy可以直接在cmd命令下使用pip安装即可,pip本质上一是安装mitmproxy库的相关代码,二是安装mitmproxy.exe,mitmdump.exe ,mitmweb.exe三个可执行程序。
pip install mitmproxy
测试是否安装成功
在cmd命令下输入: mitmdump --version,如果出现下面的提示就代表安装成功
Mitmproxy: 5.0.0
Python: 3.6.5
OpenSSL: OpenSSL 1.1.0j 20 Nov 2018
Platform: Windows-10-10.0.18362-SP0
mitmproxy 安装以后提供了三个执行程序:mitmproxy, mitmdump, mitmweb,直接在控制台输入即可。
mitmproxy:提供了 shell 交互式的抓包界面,但是只能在 Linux 环境中使用
mitmdump:后台抓包,一般windows下都是使用这个命令,本文案例就是使用它来执行抓包。
mitmweb:会在默认浏览器打开一个抓包可视化的界面,一般很少用到。
常用的参数:
-w 指定输出的文件
-s 指定抓包时执行的脚本
mitmdump -s xxx.py
设置好抓包代理后,浏览器打开链接 http://mitm.it/ ,安装CA证书,便于抓取 HTTPS 。因为篇幅有限,关于具体如何安装CA证书,可以自行搜索,在这里我就不过多赘述了。
本案例所用到的模块:
# 导入需要的模块
import subprocess
import json
from jsonpath import jsonpath
from mitmproxy import http
from pymongo import MongoClient
二、分析网页
打开西瓜视频app,然后通过fiddler抓包工具,先抓取到我们需要的数据包,如图:
既然已经知道数据在哪里,我们就来看看这个数据的具体地址和信息,如图:
通过上图可以看出,是一个get请求,请求里面包含很多的参数,这些参数让人一看就感觉没有什么规律,而且很多参数还是动态的,所以就很难做到常规的发送请求,获取响应,现在就需要利用mitmproxy这个工具抓包然后通过脚本进行实时处理并保存。我们先把抓包请求到的数据把他复制下来,以便过后分析使用。
三、mitmproxy抓包
首先必须确保已经正确安装好了mitmproxy,并且手机和电脑处于同一局域网下,同时配置好mitmproxy的CA证书。我们先写一段脚本用来捕获请求数据,
# 定义response函数(需要按照mitmproxy规则定义)
def response(self, flow: http.HTTPFlow):
if '/video/app/user/videolist_tab/v3/' not in flow.request.url:
return
text = flow.response.text
print(text)
然后设置好手机端的代理地址和端口后,就可以通过命令的方式进行mitmproxy抓包了,
# 抓包命令
mitmdump -s xxx.py
通过我们写的脚本 ,可以看到实时抓取请求到的数据:
很明显这些就是我们需要的数据,只不过这些数据看起来很乱,需要我们进一步完善这个脚本,通过我们之前复制下来请求到的数据,进行分析,进一步把数据解析出来,这些数据其实都是些json格式的数据,所以解析也不难。
def get_video_data(self, json_data, video_datas):
"""
提取数据的方法
:param json_data:
:param video_datas:
:return:
"""
for data in json_data.get('data'):
video_data_dict = {
# 提取视频标题
'video_title': data.get('title'),
# 提取视频作者名字
'author_name': data.get('user_info').get('name'),
# 提取作者的粉丝数
'author_fans_count': data.get('user_info').get('followers_count_str'),
# 提取视频的真实url地址
'video_url_data': video_datas
}
self.video.insert_one(video_data_dict)
print(video_data_dict)
def get_video_info(self, json_data):
"""
提取视频真实url地址的方法
:param json_data:
:return:
"""
for data in json_data.get('data'):
video_infos = json.loads(data.get('video_play_info'))
video_info_dict = {
'video_definition': jsonpath(video_infos, '$..definition'),
'video_urls': jsonpath(video_infos, '$..main_url'),
}
video_datas = [i for i in zip(video_info_dict.get('video_definition'), video_info_dict.get('video_urls'))]
return video_datas
现在在看看通过数据清洗和解析后请求到的数据是什么样的,如图:
现在看就清爽多了,数据每条都很清楚,最后保存到mongodb数据库。
效果展示:
可以看到里面的视频各种清晰度的都有其链接地址。