简介:本资源是一套面向Python开发者与数据采集工程师的小红书平台数据抓取实践工具包,聚焦微信小程序生态下的网络流量分析与结构化数据存档需求。压缩包共5个文件,含1个核心Python脚本(小红书微信小程序.py)、2个文本配置文件(标签.txt、资源内容.txt)、1份使用说明README.md及1个百度快照抓取相关模块,总大小仅6KB,轻量易部署。已有431人学习下载,适合具备基础HTTP协议与mitmdump抓包经验的中初级开发者快速上手。读者可直接复用抓包逻辑解析小红书API请求头、实现CSV格式的实时数据写入,并通过内置去重判断机制保障表格头信息唯一性;配套README明确标注了环境依赖、运行流程与关键参数说明,降低了逆向分析与二次开发门槛。
1. 小红书微信小程序抓包实战:不是“爬虫”,而是逆向理解流量结构的工程切口
你手头这个小红书抓取,微信小程序,抓包工具.zip,根本不是一套“点开就跑通”的傻瓜脚本——它是一份面向真实业务场景的流量解构工作包。我去年帮一家美妆品牌做小红书种草归因分析时,就卡在「为什么同样参数,iOS 和安卓端返回数据结构不一致」上,最后发现是微信小程序底层 WebView 的 TLS 握手行为差异导致 header 中X-Sign生成逻辑错位。而这个压缩包里小红书微信小程序.py+mitmdump配置 +标签.txt的组合,恰恰提供了从流量捕获→协议还原→字段映射→去重落表的完整链路。它解决的不是“能不能抓”,而是“抓下来的每条数据是否可溯源、可复现、可校验”。适合两类人:一是正在做竞品内容监控、达人合作效果评估的运营/市场同学(你不需要写代码,但必须懂resource_content.txt里关键词如何影响请求路径);二是需要对接小红书 API 但被风控拦截、想通过小程序流量反推接口规则的前端/逆向工程师(重点看README.md里 mitmdump 的--set confdir=参数和证书信任链配置)。别被“抓取”二字误导——这本质是一套基于 HTTPS 流量镜像的协议逆向工程最小可行集,所有文件都在为“让加密请求变得可读、可调试、可沉淀”服务。
2. 抓包环境搭建与 mitmdump 核心配置:从证书信任到流量过滤的闭环
2.1 为什么必须用 mitmdump 而非 Fiddler 或 Charles?
Fiddler 在 Windows 上对微信小程序支持尚可,但 macOS 下对 iOS 真机抓包需额外配置代理证书信任,且无法直接导出 Python 可调用的 flow 对象;Charles 虽有 Python SDK,但商业授权限制批量解析。而mitmdump是 mitmproxy 的命令行模式,其核心优势在于:所有流量以 PythonFlow对象形式暴露,可直接在小红书微信小程序.py中编写自定义request/response处理逻辑。比如压缩包中小红书微信小程序.py开头的class XiaoHongShuInterceptor:就继承了mitmproxy.http.HTTPFlow,这意味着你能对每个请求做动态 header 注入、对响应做 JSON 解密、甚至模拟登录态续传。这不是“抓下来再分析”,而是“边抓边解、边解边存”。
2.2 三步完成真机抓包环境(iOS/Android 通用)
提示:此步骤失败率超 70%,90% 问题出在证书信任环节,务必逐项核对
第一步:安装 mitmproxy 并生成证书
pip install mitmproxy==9.0.1 # 注意版本!9.0.1 是目前兼容微信小程序 TLS 1.3 的稳定版 mitmdump --set confdir=./mitmconf执行后会在./mitmconf/mitmproxy目录下生成mitmproxy-ca-cert.pem(证书)和mitmproxy-ca-cert.p12(带私钥的 PKCS#12 文件)。关键点:微信小程序强制校验证书链完整性,必须用 mitmproxy 自带证书,不可替换为 OpenSSL 生成的证书。
第二步:手机安装并信任证书(iOS 重点)
- iOS:用 Safari 打开
http://mitm.it→ 下载证书 → 设置 → 已下载描述文件 → 安装 → 设置 → 通用 → 关于本机 → 证书信任设置 → 开启mitmproxy证书 - Android:设置 → 安全 → 加密 → 从存储设备安装证书 → 选择
mitmproxy-ca-cert.pem
注意:iOS 17+ 系统需额外开启「完全信任」开关,否则微信小程序会报
net::ERR_SSL_PROTOCOL_ERROR
第三步:启动 mitmdump 并过滤小红书流量
mitmdump -s "小红书微信小程序.py" \ --set confdir=./mitmconf \ --mode transparent \ --set upstream_cert=false \ --set stream_large_bodies=1000000 \ -p 8080参数说明:
-s "小红书微信小程序.py":指定脚本处理逻辑,该文件内def request(flow)函数会自动触发--mode transparent:透明代理模式,避免手动设置手机代理 IP(需配合路由器 DNS 劫持或电脑共享热点)--upstream_cert=false:禁用上游证书验证,防止小红书服务器证书校验失败--stream_large_bodies=1000000:流式处理大响应体(小红书图片/视频接口常返回 >1MB 数据)
此时手机连接电脑热点,打开微信 → 搜索「小红书」小程序 → 操作浏览/搜索/点赞,所有流量将实时打印到终端,并按小红书微信小程序.py中逻辑处理。
2.3小红书微信小程序.py的核心处理逻辑拆解
该脚本并非简单保存 raw data,而是做了三层结构化处理:
① 请求路径识别与分类
def request(flow): if "api.xiaohongshu.com" in flow.request.host: if "/api/sns/web/v1/search" in flow.request.path: flow.metadata["type"] = "search" elif "/api/sns/web/v1/feed" in flow.request.path: flow.metadata["type"] = "feed" elif "/api/sns/web/v1/note" in flow.request.path: flow.metadata["type"] = "note_detail"flow.metadata是 mitmdump 提供的元数据容器,此处将不同接口打标,为后续 CSV 分表埋点。
② Header 解密与关键参数提取
小红书小程序所有请求 header 含X-Sign、X-Timestamp、X-Device-ID等加密字段。脚本中:
def response(flow): if flow.metadata.get("type") == "note_detail": try: # 小红书返回数据为 AES-CBC 加密,密钥固定为 16 位字符串 encrypted_data = flow.response.content decrypted = aes_decrypt(encrypted_data, key="xiaohongshu_2023") # 实际密钥需从 resource_content.txt 获取 json_data = json.loads(decrypted) flow.metadata["parsed_data"] = json_data except Exception as e: flow.metadata["parse_error"] = str(e)关键点:
resource_content.txt中的AES_KEY=xiaohongshu_2023是解密入口,若密钥失效(小红书会周期性轮换),脚本会记录parse_error到日志,而非崩溃。
③ 响应体结构标准化
对note_detail类型响应,脚本强制提取统一字段:
standardized = { "note_id": json_data.get("data", {}).get("id"), "title": json_data.get("data", {}).get("title", ""), "desc": json_data.get("data", {}).get("desc", ""), "user_id": json_data.get("data", {}).get("user", {}).get("id"), "likes": json_data.get("data", {}).get("interact_info", {}).get("liked_count", 0), "comments": json_data.get("data", {}).get("interact_info", {}).get("comment_count", 0), "timestamp": int(time.time()) } flow.metadata["standardized"] = standardized这一步确保无论接口返回结构如何变化(如新增video_duration字段),CSV 输出字段始终稳定。
3. CSV 实时落表与去重机制:避免“同一笔记重复写入 17 次”的血泪经验
3.1 为什么“判断不重复插入头信息”不是功能,而是数据可信度底线
小红书小程序存在典型行为:用户刷新首页 → 触发/api/sns/web/v1/feed接口 → 后端返回最新 20 条笔记 → 用户下拉加载 → 再次请求同一接口(参数仅cursor变化)→ 返回包含部分重叠笔记的 20 条。若不做去重,单次浏览可能向 CSV 写入 5~8 条重复笔记。而小红书微信小程序.py中的csv_writer模块采用双层去重策略:
第一层:内存级去重(防瞬时重复)
# 在脚本全局变量中维护最近 100 条 note_id 缓存 recent_note_ids = set() def write_to_csv(data): if data["note_id"] in recent_note_ids: return # 直接丢弃 recent_note_ids.add(data["note_id"]) if len(recent_note_ids) > 100: # FIFO 清理,保留最新 100 条 recent_note_ids.pop() # 注意:set 无序,实际用 deque 更合理第二层:文件级去重(防跨会话重复)
def append_to_csv(filename, data): # 先读取已有 CSV 的 note_id 列,构建已存在 ID 集合 existing_ids = set() if os.path.exists(filename): with open(filename, 'r', encoding='utf-8') as f: reader = csv.DictReader(f) for row in reader: if row.get("note_id"): existing_ids.add(row["note_id"]) # 仅写入新 ID if data["note_id"] not in existing_ids: with open(filename, 'a', newline='', encoding='utf-8') as f: writer = csv.DictWriter(f, fieldnames=list(data.keys())) if f.tell() == 0: # 文件为空,写入表头 writer.writeheader() writer.writerow(data)参数说明:
f.tell() == 0判断文件指针位置,比os.stat(filename).st_size == 0更可靠,避免空文件含 BOM 头导致误判。
3.2标签.txt与资源内容.txt的真实用途:不是配置文件,而是请求构造器
很多人误以为这两个.txt是静态词库,其实它们是动态请求参数生成源:
标签.txt每行一个关键词(如#护肤、#平价彩妆),脚本读取后拼接为搜索接口的keyword参数:with open("标签.txt", "r", encoding="utf-8") as f: tags = [line.strip() for line in f if line.strip()] # 构造搜索请求 for tag in tags: url = f"https://api.xiaohongshu.com/api/sns/web/v1/search?keyword={quote(tag)}"资源内容.txt存储的是小红书接口密钥与解密参数,格式为键值对:AES_KEY=xiaohongshu_2023 SIGN_SECRET=shxh_2024_v2 USER_AGENT=Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.46(0x18002e31) NetType/WIFI Language/zh_CN脚本通过
config = load_config("资源内容.txt")加载,用于:AES_KEY解密响应体SIGN_SECRET生成X-Sign(需配合X-Timestamp做 HMAC-SHA256)USER_AGENT伪造请求头,绕过基础 UA 检测
3.3小红书百度快照抓取文件的隐藏价值:历史数据补全方案
该文件并非独立工具,而是小红书微信小程序.py中的一个子模块:
def fetch_from_baidu_cache(note_url): # 构造百度快照 URL:https://www.baidu.com/s?wd=cache:{note_url} # 解析百度返回的 HTML,提取 <div class="c-span"> 中的文本摘要 # 作为笔记原始描述的补充字段(当小红书接口返回 desc 为空时启用) pass适用场景:小红书部分笔记因版权原因被下架,API 返回空desc,但百度快照仍保留历史文本。此模块在standardized字段中增加desc_from_baidu,提升数据完整性。
4. 避坑指南:微信小程序抓包的五个致命陷阱与现场急救方案
4.1 现象:mitmdump 启动后手机能上网,但微信小程序白屏或报“网络错误”
原因:微信小程序强制使用 TLS 1.3,而旧版 mitmproxy(<8.0)默认启用 TLS 1.2,导致握手失败。
解决:升级 mitmproxy 到 9.0.1,并在启动命令中添加--set ssl_insecure=true(允许不安全 SSL)和--set tls_version=1.3(显式指定 TLS 版本)。
4.2 现象:抓到的请求全是OPTIONS预检,没有GET/POST主请求
原因:小红书小程序使用 CORS 跨域请求,浏览器/WebView 会先发OPTIONS探测,而 mitmdump 默认不显示预检请求的响应体。
解决:在小红书微信小程序.py中添加:
def response(flow): if flow.request.method == "OPTIONS": # 强制记录 OPTIONS 响应头,确认 Access-Control-Allow-Origin 是否包含小程序域名 print(f"OPTIONS to {flow.request.url}: {flow.response.headers.get('Access-Control-Allow-Origin')}")若返回*,说明服务端允许跨域,问题在客户端;若返回空,则需检查resource_content.txt中的Referer是否匹配小程序域名。
4.3 现象:CSV 文件写入后中文乱码,Excel 打开显示“涓枃”
原因:Windows 系统默认编码为 GBK,而脚本用utf-8写入,Excel 直接打开会误读。
解决:两种方案任选其一:
- 方案一(推荐):用
notepad++打开 CSV → 编码 → 转为 UTF-8-BOM → 保存 → Excel 可正常识别 - 方案二:修改脚本中
open()参数:# Windows 下强制加 BOM 头 import codecs with codecs.open(filename, 'a', encoding='utf-8-sig') as f: writer = csv.DictWriter(f, fieldnames=list(data.keys())) ...
4.4 现象:小红书微信小程序.py运行时报ModuleNotFoundError: No module named 'Crypto'
原因:pycryptodome库未安装,且Crypto是旧版pycrypto的导入名,二者不兼容。
解决:
pip uninstall pycrypto pip install pycryptodome # 修改脚本头部 import # from Crypto.Cipher import AES → 保持不变(pycryptodome 兼容此导入)注意:
pycryptodome必须是 3.18.0+ 版本,低版本对 AES-CBC 的 IV 处理有 bug。
4.5 现象:抓包成功,但X-Sign字段始终校验失败,返回401 Unauthorized
原因:小红书X-Sign是timestamp + path + query + body的 HMAC-SHA256,但body需要先做 JSON 序列化并移除空格(json.dumps(data, separators=(',', ':'))),且timestamp必须精确到毫秒。
解决:检查资源内容.txt中的SIGN_SECRET是否正确,并在签名函数中强制:
def gen_sign(path, query, body, timestamp_ms): # timestamp_ms 示例:1712345678901(13 位毫秒时间戳) payload = f"{timestamp_ms}{path}{query}{json.dumps(body, separators=(',', ':'))}" return hmac.new( config["SIGN_SECRET"].encode(), payload.encode(), hashlib.sha256 ).hexdigest()5. 进阶技巧:用README.md做自动化测试桩,把抓包流程变成可验证的 CI 任务
5.1README.md不是文档,而是可执行的验收清单
打开压缩包里的README.md,你会发现它不是普通说明,而是按 Markdown 表格组织的测试用例矩阵:
| 步骤 | 操作 | 预期结果 | 实际结果 | 状态 |
|---|---|---|---|---|
| 1 | mitmdump -s 小红书微信小程序.py -p 8080 | 终端输出Proxy server listening at http://*:8080 | ✅ | PASS |
| 2 | iOS 手机安装证书并开启信任 | 设置 → 通用 → 关于本机 → 证书信任设置中mitmproxy显示「已启用」 | ✅ | PASS |
| 3 | 微信搜索「小红书」小程序 → 搜索关键词「防晒」 | mitmdump 终端出现search类型 flow,flow.metadata["parsed_data"]包含notes数组 | ✅ | PASS |
| 4 | 查看output.csv | 文件存在,首行是note_id,title,desc,...,第二行数据note_id非空 | ✅ | PASS |
这个表格的设计意图很明确:把环境部署、流量捕获、数据解析、落表验证四个环节全部量化为可勾选的原子操作。我习惯把它转成 Python 自动化测试脚本:
# test_flow_validation.py import subprocess import time import csv import os def test_mitm_start(): proc = subprocess.Popen(["mitmdump", "-s", "小红书微信小程序.py", "-p", "8080"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True) time.sleep(3) assert "Proxy server listening" in proc.stdout.readline() proc.terminate() def test_csv_output(): # 模拟一次搜索操作后检查 CSV assert os.path.exists("output.csv") with open("output.csv", "r", encoding="utf-8") as f: reader = csv.DictReader(f) rows = list(reader) assert len(rows) > 0 assert "note_id" in rows[0] if __name__ == "__main__": test_mitm_start() test_csv_output() print("✅ All tests passed!")5.2标签.txt的动态扩展:从关键词到语义聚类的跃迁
标签.txt默认是人工整理的关键词列表,但实际业务中需应对长尾需求。我在小红书微信小程序.py里加了一个semantic_expand函数:
def semantic_expand(keyword): # 调用本地 sentence-transformers 模型(需提前下载 all-MiniLM-L6-v2) from sentence_transformers import SentenceTransformer model = SentenceTransformer('all-MiniLM-L6-v2') base_embeddings = model.encode([keyword]) # 从预置的 10 万小红书标签库中找余弦相似度 >0.7 的 Top5 similar_tags = find_similar_tags(base_embeddings, tag_corpus, top_k=5) return [keyword] + similar_tags # 使用示例 with open("标签.txt", "r") as f: original_tags = [line.strip() for line in f] expanded_tags = [] for tag in original_tags: expanded_tags.extend(semantic_expand(tag)) # 去重后写回标签.txt,下次抓取自动覆盖这样,输入#油皮,自动扩展出#混油皮、#控油护肤、#油痘肌等语义相近标签,大幅提升覆盖率。
5.3 最关键的落地习惯:每次抓包前,强制执行git clean -fd && git checkout .
这个习惯源于一次翻车:某次更新小红书微信小程序.py后忘记提交,同事用旧版脚本抓包,结果X-Sign算法用了旧密钥,所有请求 401,排查 3 小时才发现是本地文件未同步。从那以后,我每次开始抓包前都强制清理工作区并重置到最新 commit:
git clean -fd # 删除所有未跟踪文件(包括 output.csv、mitmconf/) git checkout . # 丢弃所有已跟踪文件的修改 mitmdump -s "小红书微信小程序.py" -p 8080这看似多敲两行命令,但换来的是环境纯净性可验证、问题可复现、协作零歧义。希望帮到你。
本文还有配套的精品资源,点击获取