ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

小红书小程序抓包实战:mitmdump 拦截与 CSV 落库去重

小红书小程序抓包实战:mitmdump 拦截与 CSV 落库去重 简介这份资源面向希望入门网络数据采集与小程序开发的开发者聚焦小红书平台数据抓取与微信小程序场景下的流量分析。包内共5个文件以txt说明、py脚本、md文档及快照抓取文件为主压缩包约6KB体积轻量便于快速查阅。核心内容围绕mitmdump抓包工具展开讲解如何拦截、记录并分析HTTP与HTTPS流量进而解析小红书请求中的加密headers参数同时涉及将抓取结果写入CSV表格并通过判断去重避免重复插入头信息保证数据准确完整。配套的Python脚本可用于处理小红书相关抓取任务说明文档与标签、资源内容文件则提供使用指引和关键词参考。目前已有435人学习适合想了解抓包分析、数据去重与小程序数据处理的初中级开发者参考借鉴。1. 拆开这个抓包工具包小红书小程序数据怎么落到 CSV 里做小红书数据的朋友大概率都遇到过这个场景小程序里刷到的笔记、商品、用户信息想批量存下来做选品分析或竞品监控结果发现接口全是加密参数浏览器 F12 抓不到复制粘贴又太慢。这个压缩包就是冲着这个痛点来的——它把小红书微信小程序的抓取脚本、抓包配置、CSV 落库逻辑和百度快照兜底方案打包在一起核心文件是小红书微信小程序.py配套标签.txt、资源内容.txt、README.md和一个百度快照抓取模块。适合谁做小红书选品、内容运营、竞品分析的技术同学以及想搞明白小程序抓包到底怎么落地的开发者。它不解决绕过风控这种玄学问题但能把抓什么、怎么抓、怎么存、怎么去重这条链路讲清楚。2. 抓包工具选型与 mitmdump 拦截链路为什么不是 Fiddler2.1 小程序抓包和网页抓包的本质差别很多人第一反应是用 Fiddler 或 Charles 抓包这在小程序场景下会翻车。原因在于微信小程序的网络请求走的是微信自己的通信层PC 端 Fiddler 默认只能看到 HTTP/HTTPS 的明文流量而小程序的请求往往带证书校验直接抓会看到一堆 CONNECT 隧道或者干脆空白。更关键的是小红书小程序的接口参数比如shield、x-sign这类签名是在客户端侧动态生成的你抓到了 URL 也未必能复现请求。mitmdump 的优势在于它是 mitmproxy 的命令行版本支持用 Python 脚本实时处理流量。这意味着你可以在流量经过代理的瞬间用脚本修改请求头、提取响应体、甚至动态计算签名参数。对于小红书这种参数加密的平台mitmdump 的脚本能力比 Fiddler 的图形化断点强太多。常见做法是手机端设置代理指向跑 mitmdump 的机器安装 mitmproxy 的 CA 证书然后让脚本自动把匹配到的响应写入 CSV。2.2 mitmdump 脚本的骨架和参数含义下面是一个典型的 mitmdump 抓取脚本结构对应压缩包里小红书微信小程序.py的核心逻辑。我把它拆成可复现的版本你照着改域名和字段就能用# mitmdump -s xhs_capture.py -p 8080 from mitmproxy import http import csv import os import json CSV_PATH xhs_data.csv # 目标接口特征小红书的笔记列表/详情接口一般带这些路径关键词 TARGET_HOSTS [edith.xiaohongshu.com, www.xiaohongshu.com] TARGET_PATHS [/api/sns/web/v1/feed, /api/sns/web/v1/note] def response(flow: http.HTTPFlow): # 只处理目标域名和路径避免把无关流量写进 CSV if not any(h in flow.request.host for h in TARGET_HOSTS): return if not any(p in flow.request.path for p in TARGET_PATHS): return try: data json.loads(flow.response.text) except Exception: return # 从响应里提取笔记列表字段名以实际接口为准 items data.get(data, {}).get(items, []) if not items: return # 判断文件是否存在决定是否写表头 file_exists os.path.isfile(CSV_PATH) with open(CSV_PATH, a, newline, encodingutf-8-sig) as f: writer csv.writer(f) if not file_exists: writer.writerow([note_id, title, user, likes, url]) for it in items: note it.get(note_card, {}) writer.writerow([ it.get(id, ), note.get(display_title, ), note.get(user, {}).get(nickname, ), note.get(interact_info, {}).get(liked_count, ), fhttps://www.xiaohongshu.com/explore/{it.get(id, )} ])逻辑说明response函数是 mitmdump 的钩子每条响应都会进来。先按域名和路径过滤避免把图片、静态资源也写进去。json.loads解析响应体如果接口返回的不是 JSON 就跳过。file_exists判断是为了只在第一次写入时写表头这就是标题里说的判断不重复插入头信息——不是去重数据而是去重表头。参数方面-p 8080是代理端口-s指定脚本CSV_PATH可以改成绝对路径方便后续处理。2.3 手机端代理配置和证书安装脚本跑起来只是第一步手机端得把流量导过来。步骤是手机和电脑连同一个 Wi-Fi手机 Wi-Fi 设置里手动代理填电脑 IP 和 8080 端口然后浏览器访问mitm.it下载对应平台的证书iOS 需要在关于本机-证书信任设置里手动信任Android 7 以上需要把证书装到系统证书区这一步通常要 root或者用模拟器。装完证书后打开小红书小程序刷几条笔记终端里就能看到 mitmdump 打印的请求日志CSV 也会开始写入。注意小红书对代理流量有检测部分版本会直接拒绝请求。如果发现小程序加载不出来先关掉代理确认网络正常再检查证书是否装对。3. CSV 实时落库与去重逻辑表头判断和字段映射3.1 为什么用 CSV 而不是直接入库这个包选择 CSV 作为落库格式不是偷懒而是有实际考量。抓取阶段数据量不确定字段也可能随接口调整CSV 的 schema 灵活用 Excel 或 pandas 打开就能看不需要提前建表。而且 CSV 是纯文本方便后续用脚本做二次清洗。常见做法是先用 CSV 落地确认字段稳定后再导入 SQLite 或 MySQL。但 CSV 有个坑追加写入时如果每次都写表头文件就会变成表头-数据-表头-数据的混乱结构。压缩包里提到的判断不重复插入头信息就是解决这个问题的。上面的代码用os.path.isfile判断文件是否存在只有第一次才写表头。更稳妥的做法是用一个单独的标记文件或者检查文件大小是否为零# 更稳妥的表头判断文件不存在或大小为 0 才写表头 write_header (not os.path.exists(CSV_PATH)) or os.path.getsize(CSV_PATH) 0 with open(CSV_PATH, a, newline, encodingutf-8-sig) as f: writer csv.writer(f) if write_header: writer.writerow([note_id, title, user, likes, url]) # ... 写入数据行utf-8-sig这个编码很关键它会在文件开头加 BOM这样 Excel 打开中文不会乱码。如果你用 pandas 读取pd.read_csv(CSV_PATH, encodingutf-8-sig)也能正确解析。3.2 数据去重的两种策略抓取过程中重复数据很常见比如同一条笔记在推荐流和搜索结果里都出现。去重有两种做法一是在写入前用内存集合记录已见过的note_id二是写入后用 pandas 去重。内存集合适合单次会话pandas 适合事后清洗import pandas as pd # 事后去重按 note_id 保留第一条 df pd.read_csv(xhs_data.csv, encodingutf-8-sig) df.drop_duplicates(subset[note_id], keepfirst, inplaceTrue) df.to_csv(xhs_data_dedup.csv, indexFalse, encodingutf-8-sig) print(f去重前 {len(df)} 条去重后 {len(df.drop_duplicates(subset[note_id]))} 条)subset指定按哪列判重keepfirst表示保留第一次出现的记录。如果要做增量抓取可以在写入前先读一遍已有 CSV 的note_id集合新数据里如果note_id已存在就跳过。这个逻辑在小红书微信小程序.py里通常会有体现具体实现看 README 的说明。3.3 字段映射和接口变动应对小红书的接口字段名会变今天叫display_title明天可能改成title。脚本里最好做一层兼容def pick(d, *keys, default): 从字典里按优先级取第一个存在的 key for k in keys: if k in d and d[k]: return d[k] return default title pick(note, display_title, title, desc)这样接口小改不用重写脚本。标签.txt和资源内容.txt里如果有关键词列表可以加载进来做过滤只抓包含特定标签的笔记减少无关数据。4. 百度快照兜底与常见问题排查4.1 百度快照抓取的适用场景压缩包里有个小红书百度快照抓取模块这不是主力方案而是兜底。当小程序接口抓不到比如风控升级、证书校验加强时百度快照里可能还保留着笔记的文本内容。快照抓取的逻辑是构造百度搜索 URL解析搜索结果页里的快照链接再请求快照页面提取正文。这个方案的局限很明显快照更新滞后图片和视频拿不到只适合做文本层面的补充。常见做法是用它来补全标题和正文互动数据还是得靠接口。4.2 抓包过程中的五个血泪坑现象一mitmdump 启动后手机无法上网。原因通常是手机代理 IP 填错或者电脑防火墙拦了 8080 端口。解决确认电脑和手机在同一网段ifconfig或ipconfig查电脑 IP防火墙临时关闭测试。现象二小程序提示网络异常但浏览器能打开网页。这是证书没装好或没信任。iOS 要在设置-通用-关于本机-证书信任设置里打开 mitmproxy 证书的开关Android 高版本需要把证书放到系统证书目录或者用模拟器。现象三CSV 里中文乱码。编码问题写入时用utf-8-sig读取时也用同样编码。如果已经乱码了用iconv或 pandas 重新编码。现象四抓到的响应是加密的或者空的。小红书部分接口返回的是加密体需要客户端解密。这种情况脚本层面解决不了得看README.md里有没有说明解密方式或者换用百度快照兜底。现象五CSV 表头重复出现。就是前面说的表头判断问题检查os.path.isfile或getsize逻辑确保只在文件为空时写表头。4.3 抓取频率和合规边界抓取频率太高会触发风控表现为返回 461、471 状态码或者直接封 IP。建议在脚本里加延时import time import random # 在每次写入后随机休眠模拟人工浏览节奏 time.sleep(random.uniform(1.5, 4.0))这个延时加在response函数末尾或者用 mitmdump 的--set delay参数。另外抓取的数据自己分析用没问题但别公开传播或商用这是基本的边界。5. 从 CSV 到分析pandas 清洗和标签过滤的进阶技巧抓到 CSV 只是开始真正有价值的是后续分析。我一般会先用 pandas 做一轮清洗把点赞数从1.2万这种字符串转成数值再按标签过滤import pandas as pd import re df pd.read_csv(xhs_data.csv, encodingutf-8-sig) # 把 1.2万 3456 统一转成整数 def parse_count(s): s str(s).strip() if 万 in s: return int(float(s.replace(万, )) * 10000) try: return int(s) except ValueError: return 0 df[likes_num] df[likes].apply(parse_count) # 加载标签文件做过滤 with open(标签.txt, r, encodingutf-8) as f: tags [line.strip() for line in f if line.strip()] # 标题里包含任一标签的留下 pattern |.join(re.escape(t) for t in tags) df_filtered df[df[title].str.contains(pattern, naFalse)] df_filtered.to_csv(xhs_filtered.csv, indexFalse, encodingutf-8-sig) print(f过滤后剩余 {len(df_filtered)} 条)parse_count处理了中文数量单位re.escape防止标签里有正则特殊字符。标签.txt的格式一般是一行一个词如果你的文件是逗号分隔的改成split(,)就行。验证抓取是否完整可以对比小程序里实际刷到的笔记数和 CSV 行数。如果差距大检查是不是有分页接口没覆盖到或者部分响应被过滤掉了。我习惯在脚本里加一个计数器每写入一条就打印一次这样能实时看到抓取进度。从那以后我每次跑抓取脚本都会先拿 10 条数据做小样本验证确认字段映射、编码、去重逻辑都对了再放开量跑。这个习惯帮我省了很多事后清洗的麻烦。希望帮到你。本文还有配套的精品资源点击获取
返回列表