xiaohongshu-download
概述
把一条小红书笔记链接变成可直接使用的内容:视频(mp4)、图文原图(jpg + zip)、正文文案(txt)。
技术路线:用移动端 UA 请求笔记页,从页面内嵌的 window.__INITIAL_STATE__ 里直接读取笔记的标题、正文、图片直链和视频流地址,再用分块 Range 下载落盘。
> 为什么不像别的平台那样直接用 videodl?因为实测发现:小红书对数据中心 IP 的风控极严,videofetch 自带的 RednoteVideoClient(走 PC 端 UA)在本运行环境里会被重定向到 /login 或 /404/sec_...,拿不到任何数据(详见下方「实测结论」)。改用移动端 UA 后可以正常拿到公开笔记数据,这是本技能的核心。
使用边界与免责声明
- 本技能仅供个人学习、研究使用,禁止任何商业用途;
- 下载内容的版权归原作者所有,请勿传播或二次分发受版权保护的内容;
- 请只下载你有权保存的公开笔记;私密笔记、仅登录可见笔记不在支持范围;
- 脚本中的移动端 UA、Referer 注入与分块下载仅为解决运行环境网络兼容问题,使用者需自行确保下载行为符合目标平台服务条款及当地法律;
- 因使用本技能产生的一切纠纷由使用者自行承担。
你的工作方式
Phase 1:确认目标
用户已给链接就直接进 Phase 2。仅在这些情况追问:
- 没给链接;
- 一次给了多个链接——问下哪一个或全部下;
- 是纯图文笔记但用户只说"下载视频"——告知这是图文,可直接下图片。
Phase 2:环境自检(可选)
python3 -c "import requests; print('ok')" # 基础依赖
python3 -c "import sys; sys.path.insert(0,'./.pylibs'); import json_repair; print('json_repair ok')"
Phase 3:调用脚本
python3 scripts/xhs_download.py "<笔记URL>" [选项]
脚本流程:
1. xhslink.com / xhslink.cn 短链 → 跟随 302 还原成 xiaohongshu.com/... 完整链接;
2. 用移动端 UA + Referer 请求笔记页;
3. 从 window.__INITIAL_STATE__ 定位笔记对象(兼容移动端 noteData.data.noteData 与 PC note.noteDetailMap 两套结构);
4. 按 --type 决定下载视频 / 图片 / 自动判断;
5. 分块 Range 下载(每块 2 MB,单块最多重试 30 次),规避长连接被 CDN 重置;
6. 图片下载后自动打包为 .zip;--caption 另外输出 .txt。
Phase 4:交付
- 把产物路径交给用户;
- 简明报告:文件路径、大小、(图片张数)。
- 失败时按「注意事项」给出清晰原因与建议(多半是链接缺少/过期
xsec_token)。
命令参考
python3 scripts/xhs_download.py <URL> [--type auto|video|images] [--images] [--caption] [--out DIR] [--no-videodl]
| 参数 | 说明 |
|---|---|
<URL> |
笔记链接:xiaohongshu.com/explore/...、/discovery/item/...、xhslink.com/...、xhslink.cn/... |
--type auto |
默认。页面里有视频就下视频,否则按图文下图片 |
--type video |
强制视频模式;页面取不到视频流时回退了调用 videodl,再不行则退化为下图片 |
--type images / --images |
强制图文模式,下载全部原图并打包 zip |
--caption |
额外保存正文文案(标题+作者+正文+话题)到 txt,可与上面任意模式叠加 |
--out DIR |
输出目录,默认当前工作目录 |
--no-videodl |
视频模式不调用 videodl,只用页面解析 |
输出命名:<标题>.mp4(视频)/ <标题>_NN.jpg + <标题>.zip(图文)/ <标题>.txt(文案)。
stdout 末行:每个产物一行 DONE -> <路径> <字节数>。
示例对话
示例 1:下载一条图文笔记(含原图和文案)
> 用户:「帮我下这条小红书 https://www.xiaohongshu.com/explore/6abc9265...?xsec_token=ABz...&xsec_source=pc_user,图文和文案都要」
→ python3 scripts/xhs_download.py "<URL>" --images --caption
→ 输出 _01.jpg _02.jpg _03.jpg + .zip + .txt → 把文件路径交给用户。
示例 2:自动判断类型
> 用户:「把这个小红书链接里的东西都存下来 http://xhslink.com/o/xxxxx」
→ 脚本自动展开短链 → --type auto → 是视频就出 mp4,是图文就出图片 zip。
示例 3:只要无水印图片
> 用户:「只要这个小红书笔记的高清图片,不要文案」
→ python3 scripts/xhs_download.py "<URL>" --images
示例 4:链接打不开 / 被风控
> 脚本报 页面被风控或解析失败
→ 告知用户:多半是链接里的 xsec_token 缺失或已过期,请在小红书 App 里「分享 → 复制链接」拿到带 xsec_token 的完整分享链接再发一次。
运行环境
- 脚本:
scripts/xhs_download.py(相对技能根目录) - Python:3.9+
- 第三方库:
json-repair(pip install json-repair)、requests(pip install requests)、videodl(pip install videodl)
开工前先跑一次自检,缺什么当场补,别等跑到一半报错:
python3 -c "import json_repair" 2>/dev/null || echo "缺 json-repair,请执行 pip install json-repair"
python3 -c "import requests" 2>/dev/null || echo "缺 requests,请执行 pip install requests"
python3 -c "import videodl" 2>/dev/null || echo "缺 videodl,请执行 pip install videodl"
> 缺依赖时用中文告诉用户缺什么、装完就能用,不要把 Python 的英文 traceback 原样贴给用户。
注意事项(真实实测结论,务必读)
xsec_token是命门。小红书笔记详情页必须带xsec_token:App/网页「分享 → 复制链接」拿到的链接才自带它。把 token 删掉或 token 过期,页面会被重定向到/404/sec_...安全页(正文提示「当前内容仅支持在小红书 APP 内查看」),解析直接失败。token 有时效(官方 FAQ 原话是"复制后尽快使用"),越新鲜越稳。- 移动端 UA 是关键。同一
explore链接:PC 端 UA 会被重定向到/login(空页);换成 iPhone 移动端 UA 才能拿到内嵌__INITIAL_STATE__。脚本已内置移动端 UA。 - 图文图片直链是「带签名」的,不能改后缀去水印。小红书笔记图片地址形如
http://sns-webpic-qc.xhscdn.com/<ts>/<sig>/notes_pre_post/<fileId>!h5_1080jpg。
把!h5_1080jpg后缀删掉、或换成!nd_dft_wgth_webp_3、或加?imageView2/...,都会 403(签名覆盖整条路径)。脚本因此按页面给出的高画质地址原样下载(通常!h5_1080jpg= 1080px 宽 JPG,实测无水印、可直接用);想取更大原图需要登录态,运行环境不可得。 - videofetch 的
RednoteVideoClient在本运行环境不可用(实测如实报告):走 PC 端 UA,对带 token 的 explore 链接会拿到/login空页 →parsefromurl抛list index out of range;对短链会跳到/404/sec_...。所以脚本视频模式仍保留 videodl 兜底,但主力是移动端 UA 的页面解析。 - 视频流地址:脚本从笔记对象的
video子树里递归找masterUrl(失败退backupUrls,再退originVideoKey拼sns-video-bd.xhscdn.com)。masterUrl通常为无水印源。注:运行环境里未能拿到一条可公开访问的视频笔记做端到端验证(可访问的示例都是图文/过期 token),视频路径为按结构实现+兜底,图片与文案路径已验证。 - 视频/图片直链有时效:拿到地址后应尽快下载。
- 运行环境无登录态:私密笔记、需登录的笔记、更高清资源(1080p+ 视频、超清原图)由用户在本机用带 cookie 的方案获取。
资源目录
scripts/
xhs_download.py:主脚本(解析 + 分块下载 + 打包 + 文案)。
references/
notes.md:小红书风控/结构实测笔记(字段位置、实测链接、失败样本、排错表)。
上游依赖:videofetch(PyPI,装在 ./.pylibs)仅用于视频兜底;页面解析只依赖 requests + json_repair。