先介绍一下环境与工具
操作系统:MacOS
手机操作系统:Android
手机型号:荣耀8
mitmproxy: 中间人代理【man-in-the-middle proxy】,对手机端的请求进行拦截
Appium:自动化测试工具
环境搭建
在电脑上安装mitmproxy,使用如下命令安装即可
brew install mitmproxy
启用代理
mitmproxy -p 8080 #在命令行中运行,8080为代理端口
代理服务器启动后,再配置手机端连接到代理服务器,注意,手机需要与电脑处于同一个局域网下,手机连接WIFI时,点击显示高级选项,配置代理,不同的手机配置代理的地方可能不同,如下图所示:
服务器主机名填写电脑的IP地址,查看电脑IP命令如下:
ifconfig #查看电脑IP地址
服务器端口填写在电脑上启动mitmproxy时设置的端口,然后连接WIFI,接下来需要在手机端安装证书
cd ~/.mitmproxy
ls #会显示该文件夹下的所有证书
将mitmproxy-ca-cert.cer文件发送到手机上,修改后缀名为crt,然后点击安装,会弹出如下所示的界面,凭据用途选择VPN和应用
在手机上打开抖音,刷视频,在电脑上就会出现如下界面,可以抓包看到所有请求,在图中,我们可以看到视频请求返回类型是video/mp4,通过返回类型,我们可以知道哪些URL是用于请求短视频,可以看到短视频请求的域名与其他请求的域名是不同的,一级域名为xigua.com
配置android环境
因为手机的操作系统是Android,所以还需要安装android sdk,点击下载,下载完后解压安装,进入到解压目录,再进入到tools目录,执行如下命令
./android
会弹出如下窗口
玩过安卓开发的同学肯定都很熟悉了,先查看自己手机的安卓系统版本,然后下载Tools和Android 8.0.0(我的手机安卓版本是8.0.0),之后需要配置环境变量,安卓环境变量与jdk环境变量,
vi ~/.bash_profile #在该文件中添加环境变量
export ANDROID_HOME="/Users/admin/software/android-sdk-macosx" #配置自己的android sdk解压目录
export PATH="$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools"
export JAVA_HOME="/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home" #配置自己的jdk安装目录
export PATH="$JAVA_HOME/bin:$PATH"
source ~/.bash_profile #使环境变量生效
env #查看当前环境变量
adb调试
手机连接到电脑后,在终端输入命令
adb devices #会显示当前的连接设备
如果连接设备为空,则需要进行一些其他操作,以下是我的解决方案
4.1 生成adb_usb.ini文件
cd ~/.android
查看有无adb_usb.ini文件,没有的话则执行下面的命令
android update adb #会生成adb_usb.ini文件
再输入如下命令
system_profiler SPUSBDataType #查看Mac系统所有已连接USB设备信息
找到Vendor ID的值,将值0x8086添加到adb_usb.ini文件中
4.2 进入手机设置,【设置】->【系统】->【关于手机】-> 连续点击7次【版本号】,则会开启开发者模式
4.3 【设置】->【系统】->【开发人员选项】,开启【usb调试】,找到【usb配置】后,随意切换一个,再切换成【MTP】
4.4 解决未授权
adb devices #显示连接设备
如果上图红框处出现的是unauthorized,则需要在手机【开发人员选项】下点击【撤销USB调试授权】,然后找到【usb配置】,随意切换一个,再切换成【MTP】
连接设备成功的界面如上图所示
配置appium
在电脑上安装appium,下载dmg安装包安装或者使用命令行安装都行。 打开appium,在configurations中配置JAVA_HOME与ANDROID_HOME,完成后点击Start Server
再点击上图中红色框中的按钮
参数讲解
platformName:平台名称,一般是Android或iOS
deviceName:设备名称,手机的具体类型,可以随便给
appPackage:App程序包名
appActivity:入口Activity名,通常以.开头
adb logcat> ~/appium.log #并且在手机打开抖音app,在生成的appium.log中查找appPackage,appActivity的值,之后Start Session,查看是否能够控制手机,参数有无问题
编写程序
mitmproxy事件里面有3个事件是比较重要的,mitmproxy官方文档
start 启动的时候被调用,会替换当前的插件,可以用此事件注册过滤器.
request(flow) 当发送请求时,被调用.
response(flow) 当接收到回复时被调用.
import requests
import logging
# 文件路径
path = '/Users/admin/Desktop/vedios/'
num = 1
logging.basicConfig(level=logging.INFO,#打印的日志级别
filename='mitmproxy.log', #日志文件名
filemode='a',#模式,有w和a,w就是写模式,每次都会重新写日志,覆盖之前的日志,a是追加模式,默认如果不写的话,就是追加模式
format='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s' #日志格式
)
def response(flow):
global num
if ".ixigua.com/" in flow.request.url: # 过滤掉不需要的url
logging.info(flow.request.url) #记录url信息
# 设置视频名
filename = path + str(num) + '.mp4'
# 将视频写入文件夹
with open(filename, 'ab') as f:
f.write(flow.response.content)
f.flush()
num += 1
将上述代码保存成pymobile.py文件,运行mitmproxy命令时使用如下命令
mitmproxy -p 8080 -s pymobile.py #启动时运行该脚本
在IDE中编写如下代码,文件名为simulation.py
from appium import webdriver
# 报错No module named 'appium',原因:没有安装appium client, 解决方案pip install appium-python-client
from time import sleep
class Action():
def __init__(self):
# 初始化配置,设置Desired Capabilities参数,使用上面在appium中测试的参数
self.desired_caps = {
"platformName": "Android",
"deviceName": "device",
"appPackage": "com.ss.android.ugc.aweme",
"appActivity": ".main.MainActivity",
"noReset": True # 默认为False,打开APP后之前的登录会被注销,且需要重新对APP进行授权,进入初始化状态(类似于刚下载的APP),所以使用True
}
# 指定Appium Server
self.server = 'http://localhost:4723/wd/hub'
# 新建一个Session
self.driver = webdriver.Remote(self.server, self.desired_caps)
# 设置滑动初始坐标和滑动距离
self.start_x = 500
self.start_y = 1500
self.distance = 1300
def comments(self):
sleep(10)
def scroll(self):
# 无限滑动
while True:
# 模拟滑动
self.driver.swipe(self.start_x, self.start_y, self.start_x,self.start_y-self.distance)
# 设置延时等待
sleep(2)
def main(self):
self.comments() #开启会先睡眠10s
self.scroll() #滑动屏幕
if __name__ == '__main__':
action = Action()
action.main()
至此,所有工作已完成
自动化爬取视频操作步骤:
1. 启动代理mitmproxy
mitmproxy -p 8080 -s pymobile.py
2. 手机配置代理
3. 打开appium,start server
4. 运行simulation.py文件
运行时,可以使用如下命令查看到代码中设置的日志在不断的打印
tail -f mitmproxy.log
爬取的视频如下,是不带有抖音水印的噢!