mitmproxy简介
mitmproxy(man-in-the-middle attack proxy),中间人攻击工具,可以用来拦截、修改、保存 HTTP/HTTPS 请求,对于爬虫尤其是基于APP的爬虫来说,是必不可少的一款神器。mitmproxy 基于Python开发,可以通过Python代码对请求和响应进行自定义过滤和修改。
对应其安装,可以到其官网(https://www.mitmproxy.org/)下载对应操作系统的安装文件,本文略去安装过程。
mitmproxy 默认监听本地的8080端口,本文以Windows平台为例,通过使用 mitmdump(命令行模式,主要使用python脚本做交互) 或者 mitmweb (对应图形界面)命令开启mitmproxy,例如执行 mitmweb 之后,会在浏览器自动打开http://127.0.0.1:8081/#/flows页面,在浏览器的新的选修卡中打开百度首页,在上面的页面可以看到 浏览器数据包,见下图。
mitmproxy抓包
mitmproxy代理软件的强大之处在于对 python 脚本的支持,本次的目标: 在PC端访问 抖音用户 分享链接 https://www.iesdouyin.com/share/user/88445518961页面时,会看到该用户发表的视频作品列表,如下图:
通过浏览器可以看到 加载 作品的异步请求为XHR,请求地址:
https://www.iesdouyin.com/web/api/v2/aweme/post/?user_id=88445518961&sec_uid=&count=21&max_cursor=0&aid=1128&_signature=WIBR-xAfBQlRzCvu3x3D4liAUe&dytk=7450aa3aef3feced81c810744bd2b79f,对应的请求参数有多个,其中 _signature 参数值是由前端 js 生成的加密值,每次请求均不同,感兴趣的朋友可以试着 破解下,如果你不想破解这个参数,请继续看本文下面的部分。
下面开始编写 python脚本抓取刚才上面那个包含加密参数的请求url地址,脚本内容保存在mitm_addons.py文件中。
import mitmproxy.http
from mitmproxy import ctx
import json
filter_host='www.iesdouyin.com' #目标主机
url_paths='/web/api/v2/aweme/post/?user_id=' # 网页 路径指纹
class Counter:
def __init__(self):
self.num = 0
def request(self, flow: mitmproxy.http.HTTPFlow):
global filter_host,url_paths
if flow.request.host != filter_host or not flow.request.path.startswith(url_paths):
return
self.num = self.num + 1
ctx.log.info("We've seen %d flows" % self.num)
class Joker:
def request(self, flow: mitmproxy.http.HTTPFlow):
pass
def response(self, flow: mitmproxy.http.HTTPFlow):
global filter_host,url_paths
if flow.request.host != filter_host or not flow.request.path.startswith(url_paths):
return
text = flow.response.get_text()
texts = self.deal_content(text)
if not texts:
print('null')
return
for a,b in texts:
print(a)
print(b)
print('\n')
def deal_content(self, a):
b=json.loads(a)
c=b.get('aweme_list')
if not c:#c --> list of dicts
return ''
print('Found {} results.\n'.format(len(c)))
rst=[]
for i in c:
j=i['statistics']
info='播放次数:{} 评论数:{} 分享:{} 转发:{} 挖掘:{}'.format(j['play_count'],j['comment_count'],j['share_count'],j['forward_count'],j['digg_count'])
#k=i['video']['download_addr']['url_list']
#k=i['video']['play_addr_lowbr']['url_list']
k=i['video']['play_addr']['url_list']
ll='\n'.join(k)
rst.append((info,ll))
return rst
addons = [
Counter(),
Joker(),
]
对上面的代码简单解释下,过滤的目标主机是 www.iesdouyin.com,url中包含(这里是起始部分是)’/web/api/v2/aweme/post/?user_id=’,而其中的两个类,Counter用于对满足条件的数据包进行计数,Joker类用于过滤数据包,对应不满足条件的数据包直接转发,而满足条件的数据包,则对其做处理,代码中将结果打印在命令行中。
完整流程:
将上面代码保存好之后,通过命令行进入脚本文件所在目录,执行:
mitmdump -q -s mitm_addons.py
然后再通过新的命令行窗口,打开谷歌浏览器,忽略证书错误,同时对其设置了局部代理:
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --proxy-server=127.0.0.1:8080 --ignore-certificate-errors
在浏览器中打开网页:https://www.iesdouyin.com/share/user/88445518961
最终效果如下图:
其中的各个网址即为对应各个短视频的观看地址,可以在浏览器尝试打开,通过浏览器插件或者使用火狐浏览器 修改浏览器的 user-agent,可以正常观看或者下载视频。
上面的脚本结合selenium可以实现 对目标网站的批量抓取,感兴趣的朋友可以尝试下。