使用mitmdump爬取
操作系统:window 10
python 版本:python 3.6.5
抓包工具fiddler、mitmproxy
工具结介绍
fiddler就不介绍了,是常用的抓包工具。这里介绍一下mitmproxy。
mitmproxy是一个支持HTTP和HTTPS的抓包程序,有类似于Fiddler、Charles的功能,只不过它是一个控制台的形式操作。
mitmproxy还有两个关联组件。一个是mitmdump,它是mitmproxy的命令行接口,利用它我们可以对接Python脚本,用Python实现监听后的处理。另一个就是mitmweb,它是一个Web程序,通过它我们可以清楚的观察mitmproxy捕获的请求。
背景说明
工作需求,需要抓取一些国内热门软件的app内的内容,由于这些app存在很高的反爬机制,对url进行了各种加密,试了一段时间,难度太大就放弃了。改用mitmproxy中间人的特性获取所需信息。
准备工作
确保已经安装好了fiddler和mitmproxy,并且手机和PC处于同一局域网下,同时配置好fiddler和mitmproxy的CA证书。
1.fiddler抓包
fiddler运行于自己的PC上,代理端口8888,手机设置PC的IP及8888端口代理。抓取软件为抖音,需要抓取的内容为点赞后收藏的视频。找到收藏列表的api;
2.分析json数据
在fiddler上分析api上的json数据找到需要的字段,获取无水印视频地址、封面地址和视频名称,代码如下:
import json
import random
import pymysql
def response(flow):
url = 'https://api.amemv.com/aweme/v1/aweme/favorite/'
if flow.request.url.startswith(url):
text = flow.response.text
data = json.loads(text)
for item in data['aweme_list']:
desc1 = item['desc']
if desc1 == ' ' or len(desc1) == 0:
desc1 = 'adsf' + str(random.randint(1, 9999))
if '@抖音小助手' in desc1:
desc1 = desc1.replace('@抖音小助手', '')
video_url = item['video']['play_addr']['url_list'][0]
cover_url = item['video']['cover']['url_list'][0]
print(video_url,cover_url,desc1)
3.mitmdump运行脚本
命令:mitmdump -s xxx.py
进入抖音,点击收藏列表手动滑动,在控制台可以看见输出的视频地址、图片地址及名称。
4.存入数据库
将获取的信息存入mysql数据库,代码省略;
5.下载视频代码
编写下载视频的py文件,这个文件是需要部署在服务器上的,从mysql中取地址进行下载。
import os
from urllib.request import urlretrieve
import pymysql
conn = pymysql.connect(
host='xxxxxx',
port=3306,
user='root',
db='xxxx',
password='xxxxxxx',
charset='utf8mb4' #可以存储文字表情
)
cursor = conn.cursor()
sql = "select video_url,cover_url,desc1 from xxx"
cursor.execute(sql.encode('utf8'))
data = cursor.fetchall()
for item in data:
video_url = item[0]
cover_url = item[1]
desc1 = item[2]
path = 'xxxxx'
if not os.path.exists(path):
os.mkdir(path)
video_path = path + '/' + desc1 + '.mp4'
cover_path = path + '/' + desc1 + '.jpg'
try:
if not os.path.exists(video_path):
urlretrieve(video_url, video_path)
print(desc1,'视频下载完成')
else:
print(desc1, '该视频已经下载')
except OSError:
print(desc1,'该视频下载失败')
try:
if not os.path.exists(cover_path):
urlretrieve(cover_url, cover_path)
print(desc1,'该封面下载完成')
else:
print(desc1, '该封面已经下载')
except OSError:
print(desc1,'该封面下载失败')
conn.close()
这样在本地获取地址,存入数据库,服务器上的爬虫在进行下载,虽然操作麻烦了点,但是可以避开需要**加密的步骤。我这里由于是只下载收藏的列表,所以手动滑动,如果量大或者下载首页的视频,可以试一下用Appium实现自动化,关于Appium有时间再写。