App 爬虫抓包与数据采集实战——mitmproxy + Fiddler

发布时间:2026/6/26 22:21:01

App 爬虫抓包与数据采集实战——mitmproxy + Fiddler 很多数据只在 App 上有网页版要么没有要么做了反爬。这一篇讲怎么抓 App 的包、怎么解析接口、怎么用 Python 自动化采集。一、抓包原理App 和服务器通信走 HTTP/HTTPS 协议抓包就是在中间截获请求和响应。App → 抓包工具 → 服务器 ↓ 记录请求数据URL、参数、请求头、响应两种抓包方式方式工具适用场景难度代理抓包Fiddler、Charles简单新手首选⭐中间人代理mitmproxy可编程、可自动化⭐⭐二、Fiddler 抓包——快速上手1. 设置 Fiddler打开 Fiddler → Tools → Options → HTTPS勾选Capture HTTPS CONNECTs勾选Decrypt HTTPS traffic弹出证书安装提示点 Yes2. 手机连接代理手机和电脑连同一个 Wi-Fi手机 Wi-Fi 设置 → 代理 → 手动填入电脑的 IP 和 Fiddler 端口默认 8888手机浏览器访问http://电脑IP:8888下载安装 Fiddler 根证书3. 开始抓包手机上操作目标 AppFiddler 里就能看到所有 HTTP 请求。关注这几个信息URL → 接口地址 Method → GET/POST Headers → Cookie、Token、User-Agent Body → 请求参数 Response → 返回数据JSON 格式找接口的技巧在 Fiddler 里按接口域名筛选排除广告 SDK、统计 SDK 等无关请求。三、mitmproxy——Python 自动化抓包Fiddler 适合手动分析mitmproxy 适合写脚本自动化处理。1. 安装pipinstallmitmproxy启动mitmweb# 启动带 Web 界面的代理默认端口 8080浏览器打开http://127.0.0.1:8081就能看到实时请求。2. 手机配置和 Fiddler 一样手机 Wi-Fi 代理设为电脑 IP:8080访问mitm.it安装证书。3. 编写拦截脚本# capture.pyfrommitmproxyimporthttpimportjsondefrequest(flow:http.HTTPFlow):拦截请求urlflow.request.pretty_url# 只关注目标接口ifapi.target.cominurl:print(f[请求]{flow.request.method}{url})print(f[请求头]{dict(flow.request.headers)})ifflow.request.methodPOST:print(f[请求体]{flow.request.text})defresponse(flow:http.HTTPFlow):拦截响应urlflow.request.pretty_urlifapi.target.cominurl:print(f[响应]{url})dataflow.response.textprint(f[响应数据]{data[:500]})# 只打印前 500 字符运行mitmweb-scapture.py4. 自动保存数据到文件# save_data.pyfrommitmproxyimporthttpimportjsonimportosfromdatetimeimportdatetimeclassAppDataCollector:def__init__(self):self.data_filefapp_data_{datetime.now().strftime(%Y%m%d_%H%M%S)}.jsonlself.results[]defresponse(self,flow:http.HTTPFlow):urlflow.request.pretty_url# 过滤目标接口if/api/product/listinurl:try:datajson.loads(flow.response.text)# 提取商品列表productsdata.get(data,{}).get(list,[])forpinproducts:item{id:p.get(id),name:p.get(name),price:p.get(price),sales:p.get(sales),crawl_time:datetime.now().isoformat()}self.results.append(item)# 实时写入文件withopen(self.data_file,a,encodingutf-8)asf:f.write(json.dumps(item,ensure_asciiFalse)\n)print(f已采集{len(products)}条商品数据)exceptExceptionase:print(f解析失败:{e})addons[AppDataCollector()]mitmweb-ssave_data.py手机滑动 App 商品列表数据自动保存到本地。四、App 爬虫的常见问题1. 证书校验SSL Pinning很多金融类、支付类 App 做了证书绑定装了代理证书也无法抓包。解决方案# 方案一用 Android 模拟器 Xposed 框架# 安装 JustTrustMe 模块绕过证书校验# 方案二用 Frida 动态注入更通用pipinstallfrida-tools frida-U-fcom.target.app-lbypass_ssl.js// bypass_ssl.jsFrida 脚本示例Java.perform(function(){vartrustManagerJava.use(javax.net.ssl.X509TrustManager);// 覆盖证书校验方法直接通过trustManager.checkServerTrusted.implementationfunction(){// 什么也不做跳过校验};});2. 请求签名App 的接口参数往往经过加密或签名直接模拟请求会失败。# 分析签名生成逻辑# 常见情况把所有参数按字典序排序 拼接密钥 MD5defgenerate_sign(params,secret_keyxxx):模拟 App 的签名算法sorted_keyssorted(params.keys())raw.join([f{k}{params[k]}forkinsorted_keys])rawsecret_keyreturnhashlib.md5(raw.encode()).hexdigest()更省事的做法用 mitmproxy 拿到完整的请求直接用 Python 的 requests 复现。3. 请求头补全App 发起的请求通常有固定特征缺了某个头就会返回 403。headers{User-Agent:Mozilla/5.0 (Linux; Android 13; Xiaomi 13) AppleWebKit/537.36,Content-Type:application/json; charsetutf-8,Accept-Encoding:gzip,x-app-version:3.2.1,x-device-id:sn-xxxxxxxxxxxx,Authorization:Bearer xxxxxx# Token 一般在登录后获取}4. 参数加密抓包也看不到原文现在的 App 很多把参数放在加密的 body 里抓包看到的是乱码。# 逆向分析加密算法用反编译工具# jadx-gui 反编译 APK搜索 encrypt、sign、MD5 等关键词# 或者用更简单的方法hook 加密函数# Frida 脚本 hook 加密方法在运行时输出明文参数五、App 爬虫全流程示例以抓取某电商 App 商品列表为例# 步骤一用 mitmproxy 分析接口# 找到商品列表接口 /api/v2/product/list# 参数page、page_size、category_id# 签名算法md5(page page_size category_id secret)# 步骤二在 Python 中复现importrequestsimporthashlibimporttimeclassAppSpider:def__init__(self,tokenNone):self.sessionrequests.Session()self.session.headers.update({User-Agent:Mozilla/5.0 (Linux; Android 14; Pixel 8) AppleWebKit/537.36,x-app-version:4.5.0,Authorization:fBearer{token}iftokenelse,})defgenerate_sign(self,params):复现 App 的签名算法secretyour_secret_key# 通过反编译 APK 得到sorted_keyssorted(params.keys())raw.join([f{k}{params[k]}forkinsorted_keys])secretreturnhashlib.md5(raw.encode()).hexdigest()defget_products(self,category_id,page1):urlhttps://api.target.com/v2/product/listparams{page:page,page_size:20,category_id:category_id,timestamp:int(time.time()),}params[sign]self.generate_sign(params)respself.session.get(url,paramsparams)ifresp.status_code200:returnresp.json()else:print(f请求失败:{resp.status_code}{resp.text})returnNonedefcrawl_all(self,category_id,max_pages50):翻页采集所有商品all_products[]forpageinrange(1,max_pages1):dataself.get_products(category_id,page)ifnotdata:breakproductsdata.get(data,{}).get(list,[])ifnotproducts:print(f第{page}页没有数据采集结束)breakall_products.extend(products)print(f第{page}页已采集{len(all_products)}条)time.sleep(1)# 不要太快returnall_products# 使用spiderAppSpider(tokenyour_token)resultsspider.crawl_all(category_id手机)六、App 爬虫 vs Web 爬虫对比项Web 爬虫App 爬虫数据格式HTML 解析麻烦通常是 JSON解析简单反爬方式IP 封禁、验证码签名校验、SSL Pinning接口变更频率相对稳定版本更新可能改动大数据完整度可能缺少 App 专有数据数据更全如推荐算法数据上手难度简单requests 就行需要抓包和逆向建议优先考虑 Web 爬虫Web 拿不到或太难拿了再考虑 App 爬虫。总结App 爬虫的核心流程就四步装代理证书 → 抓包分析接口 → 识破签名算法 → 用代码复现请求遇到 SSL Pinning 就上 Frida遇到加密就用反编译工具分析 APK。但也要注意——App 爬虫比 Web 爬虫更靠近灰色地带采集数据时注意合规性不要采集用户隐私信息。 觉得有用的话点赞 关注【张老师技术栈】吧每周更新 Java/Python/爬虫 实战干货不让你白来。

相关新闻