| --- |
| title: XHS |
| emoji: 🦀 |
| colorFrom: blue |
| colorTo: purple |
| sdk: docker |
| pinned: false |
| --- |
| |
| Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference |
| <div align="center"> |
|
|
| # Spider_XHS |
| |
| **专业的小红书数据采集 & 全域运营解决方案 & Agent Skills** |
| |
| [](https://www.python.org/) |
| [](https://nodejs.org/) |
| [](LICENSE) |
| |
| </div> |
| |
| > **在 AI 大模型爆发的时代,内容运营的竞争本质是效率竞争。** |
| > 本项目封装了小红书平台完整的数据采集与内容发布能力,为开发者构建 AI 运营智能体提供可靠、稳定的底层 API 支撑。 |
| > **本项目已升级为「稳定性大脑 + 三引擎自动降级 + AI Agent 全链路闭环」架构:服务端自动执行 API 协议采集 + Playwright Stealth + 基于大模型视觉的 Agentic Crawler,并支持 AI Agent 全自动发布笔记与自动触达私信线索。** |
| |
| **⚠️ 本项目仅供学习交流使用,禁止任何商业化行为,如有违反,后果自负** |
| |
| --- |
| |
| ## 为什么需要这个项目? |
| |
| ``` |
| 采集竞品笔记 ──► [Spider_XHS] ──► 你的 AI Agent(改写 / 生成 / 分析)──► 自动上传发布 |
| ▲ │ |
| └──────────── 获取数据 / 管理账号 ◄──────────────────────┘ |
| ``` |
| |
| 小红书没有开放完整的内容运营接口。想要接入 AI 大模型实现内容批量采集、智能改写、一键发布,首先需要能**稳定读写平台数据**。Spider_XHS 解决的正是这个前置问题: |
| |
| - 逆向还原了小红书 PC 端与创作者平台的签名算法(x-s / x-t / x-s-common / x_b3_traceid / sign / q-signature参数) |
| - 封装全部核心 HTTP 接口,签名参数已透明处理 |
| - 同时覆盖 **数据采集**(PC端)、**内容发布**(创作者平台)、**KOL数据**(蒲公英)三大场景 |
| |
| **你负责接 AI 大脑,我们负责打通小红书的神经。** |
| |
| --- |
| |
| ## ⭐ 已实现功能 |
| |
| | 模块 | 功能 | 状态 | |
| |------|------|------| |
| | **小红书 PC 端** | 二维码登录 / 手机验证码登录 | ✅ | |
| | | 获取主页所有频道 & 推荐笔记 | ✅ | |
| | | 获取用户主页信息 / 自己的账号信息 | ✅ | |
| | | 获取用户发布 / 喜欢 / 收藏的所有笔记 | ✅ | |
| | | 获取笔记详细内容(无水印图片 & 视频) | ✅ | |
| | | 搜索笔记 & 搜索用户 | ✅ | |
| | | 获取笔记评论 | ✅ | |
| | | 获取未读消息 / 评论@提醒 / 点赞收藏 / 新增关注 | ✅ | |
| | **创作者平台** | 二维码登录 / 手机验证码登录 | ✅ | |
| | | 上传图集作品 | ✅ | |
| | | 上传视频作品 | ✅ | |
| | | 查看已发布作品列表 | ✅ | |
| | **蒲公英平台** | 获取 KOL 博主列表 & 详细数据 | ✅ | |
| | | 获取博主粉丝画像 & 历史趋势 | ✅ | |
| | | 发起合作邀请 | ✅ | |
| | **千帆平台** | 获取分销商列表 & 详细数据 | ✅ | |
| | | 获取分销商合作品类 / 店铺 / 商品信息 | ✅ | |
| |
| --- |
| |
| ## 🌟 核心特性:稳定性大脑与 AI Agent 多链路容灾 |
| |
| 为了解决小红书日益严格的风控(封号、验证码、前端频繁改版)问题,本项目重构了底层的采集架构,全面升级为**三自动引擎 + RPA 回传兜底 + 稳定性大脑 (Stability Controller)** 模式,完美适配生产级高可用业务需求。 |
| |
| ### 1. 稳定性大脑与资源池化 |
| 不再将异常写死在爬虫逻辑中,而是引入统一的 `Stability Controller`,并辅以三大资源池,实现防封禁的生命周期管理: |
| - **Account Pool(账号池)**:自动管理多账号风险分,遭遇高频风控时触发防封冷却窗。 |
| - **Session Pool(会话池)**:兼容 API 登录态与浏览器 Storage State,支持失效检测与自动轮换。 |
| - **Proxy Pool(代理池)**:支持多数据源动态拉取 IP,根据网络响应执行同步打分,自动剔除高失败率代理。 |
| - **Agentic Captcha Solver**:智能风控解除。系统在遇到复杂验证码时,会自动唤醒基于 `browser-use` 和视觉大模型的 Agent,自动完成滑块拖动和文字点选。 |
| |
| ### 2. 自动化主采集链路(三引擎容灾) |
| 提供标准的 FastAPI 轻量服务,服务端自动执行三大引擎: |
| - **Engine A (API 协议引擎)**:通过逆向签名算法直接请求接口。极速、并发高、资源占用极小,作为绝对主力。 |
| - **Engine B (Browser 浏览器引擎)**:引入 Playwright 自动化框架,并提供 Stealth 脚本注入与随机拟人化动作(鼠标轨迹、滚动,支持开关)以降低自动化特征。 |
| - **Engine D (Agentic Crawler)**:引入了**基于视觉大模型的自适应页面提取引擎**。当小红书前端 DOM 结构发生变化导致 Engine B 的固定解析规则失效时,系统自动降级唤醒 Engine D,大模型会自己“看”懂页面并提取标题、作者、正文等结构化数据,无视任何前端改版。 |
| |
| ### 3. 人工兜底链路(Chrome 插件 RPA 回传) |
| Chrome 插件并不是服务端“自动执行的第三引擎线程”,而是一个**最后的人工兜底通道**:当所有自动引擎和 AI Agent 都无法突破风控,任务自动进入 `WAITING_RPA` 时,运营人员在真实浏览器环境下采集页面内容/数据后,通过插件调用服务端回传接口完成闭环。 |
|
|
| ### 4. 人工兜底采集链路(Excel 导入解析) |
| 在极端情况下(如全网 IP 被封或大面积升级),支持通过**小红书数据助手**或第三方平台导出的 Excel 进行全量解析: |
| - 提供 `/api/v1/import/excel` 接口,自动识别各种变体表头(曝光、阅读、互动、转粉等)。 |
| - 自动完成字段映射、标准化清洗,将离线人工数据无缝对接到自动化流中,确保业务“不断流”。 |
|
|
| ### 5. 企业级运维保障 |
| - **防雪崩限流**:内置基于 IP 的滑动窗口限流(Rate Limit),超过阈值返回 `429 Retry-After`。 |
| - **普罗米修斯监控**:暴露 `/api/v1/metrics` 接口,直出 `spider_xhs_tasks_total`、`spider_xhs_recent_failure_rate` 等核心指标。 |
| - **并发与持久化**:采用基于 `fcntl.flock` 的文件锁分片存储,保证跨进程写文件的绝对原子性。 |
| - **回调重试机制**:支持结果 Webhook 推送,内置 `Idempotency-Key` 幂等控制与指数退避重试。 |
|
|
| ### 6. AI 自动化获客编排 (Orchestrator MVP) |
| 基于采集服务之上,新增轻量级 Python 编排脚本与 SQLite 本地数据库,提供完整的获客流转: |
| - **采集同步与清洗**:`crawl_sync.py` & `note_cleaner.py` |
| - **AI 批量生成图文**:`ai_generation.py` |
| - **AI 全自动发布笔记**:`publish_tracker.py`(接入 `browser-use`,大模型直接操控创作者中心) |
| - **AI 全自动触达线索**:`lead_service.py`(AI 自动打开小红书网页版私信,向高意向用户发送留资话术) |
| - **飞书同步与告警**:`feishu_sync.py` & `alert.py` (Mock 流转) |
|
|
| ### 7. 运营控制台可视化 |
| 提供基于 React + Vite 的前端可视化看板(`frontend/`),支持资源池(账号/会话/代理)健康度监控、任务错误聚合扫描以及底层 SQLite 内容库的只读分页检索,实现了前后端数据链路的直观打通。 |
|
|
| --- |
|
|
| ## 🤖 接入 AI 智能体 |
|
|
| Spider_XHS 天然适合作为 AI 运营 Agent 的数据底座,以下是几种典型用法: |
| |
| ### 场景一:竞品笔记采集 + AI 改写 + 自动发布 |
| |
| ```python |
| from apis.xhs_pc_apis import XHS_Apis |
| from apis.xhs_creator_apis import XHS_Creator_Apis |
|
|
| pc_api = XHS_Apis() |
| creator_api = XHS_Creator_Apis() |
| |
| # 1. 采集竞品笔记 |
| success, msg, note = pc_api.get_note_info(note_url, cookies_str) |
|
|
| # 2. 交给 AI 改写(接入任意大模型) |
| rewritten = your_ai_agent(note['content']) # GPT / Claude / Qwen / 本地模型 |
|
|
| # 3. 自动上传到创作者平台 |
| creator_api.post_note({ |
| "title": rewritten['title'], |
| "desc": rewritten['desc'], |
| "media_type": "image", |
| "images": [...], |
| ... |
| }, creator_cookies_str) |
| ``` |
| |
| ### 场景二:关键词监控 + AI 情报分析 |
|
|
| ```python |
| # 搜索指定关键词的最新笔记,交给 AI 分析趋势 |
| success, msg, notes = pc_api.search_some_note(query, require_num, cookies_str, ...) |
| analysis = your_ai_agent(notes) |
| ``` |
|
|
| ### 场景三:KOL 筛选 + 智能匹配 |
|
|
| ```python |
| from apis.xhs_pugongying_apis import PuGongYingAPI |
| |
| pgy = PuGongYingAPI() |
| # 获取目标类目的 KOL 数据,交给 AI 评估匹配度 |
| kol_list = pgy.get_some_user(num=50, cookies=cookies) |
| best_kols = your_ai_agent(kol_list, brand_profile) |
| ``` |
|
|
| --- |
|
|
| ## 🧩 Skills 支持 |
|
|
| 当前项目已经支持基于 skills 的能力接入,既可以直接作为 `Spider_XHS` 的底层能力仓库使用,也可以通过标准化 skills 方式被上层 Agent 工具链引入。 |
|
|
| 如果你希望直接复用已经封装好的 skills,可以直接使用本项目内置的 Agent Skills。该模块目前可被 `Clawbot`、`Claude Code`、`Codex` 等支持 skills 的工具直接引入与集成。 |
|
|
| --- |
|
|
| ## 🎨 爬虫效果图 |
|
|
| ### 处理后的所有用户 |
|  |
|
|
| ### 某个用户所有的笔记 |
|  |
|
|
| ### 某个笔记具体的内容 |
|  |
|
|
| ### 保存的 Excel |
|  |
|
|
| --- |
|
|
| ## 🛠️ 快速开始 |
|
|
| ### ⛳ 环境要求 |
|
|
| - Python 3.10+ |
| - Node.js 20+ |
|
|
| ### 🎯 安装依赖 |
|
|
| ```bash |
| pip install -r requirements.txt |
| npm install |
| ``` |
|
|
| ### 🧩 Playwright(必选:用于 Browser 引擎兜底与扫码登录) |
|
|
| 如果你希望使用**浏览器引擎 (MediaCrawler) 作为兜底策略**,或使用“内置浏览器扫码登录后自动获取 Cookie 并写回 `.env`”功能,必须安装 Playwright 浏览器内核: |
|
|
| ```bash |
| playwright install chromium |
| ``` |
|
|
| ### 🎨 配置 Cookie |
|
|
| 在项目根目录的 `.env` 文件中填入你的登录 Cookie: |
|
|
| ``` |
| COOKIES='<YOUR_XHS_COOKIE>' |
| ``` |
|
|
| Cookie 获取方式:浏览器登录小红书后,按 `F12` 打开开发者工具 → 网络 → Fetch/XHR → 找任意一个请求 → 复制请求头中的 `cookie` 字段。 |
|
|
|  |
|
|
|  |
|
|
| > **注意:必须是登录后的 Cookie,未登录状态无效。** |
|
|
| ### 🚀 运行项目 |
|
|
| ```bash |
| python main.py |
| ``` |
|
|
| ### 🧰 CLI(推荐) |
|
|
| 项目提供 CLI 方便团队跑批与断点续跑(默认状态文件 `datas/state.json`): |
|
|
| ```bash |
| python cli.py --help |
| ``` |
|
|
| #### 扫码登录并自动写回 Cookie(推荐) |
|
|
| ```bash |
| python cli.py login pc-qrcode --save-cookies --write-env |
| ``` |
|
|
| 成功后会同时写入: |
|
|
| - `datas/cookies.json` |
| - `.env` 中的 `COOKIES="..."` |
|
|
| #### 抓取示例 |
|
|
| ```bash |
| python cli.py note --url 'https://www.xiaohongshu.com/explore/xxxx?...' --save-choice excel --excel-name demo --resume |
| python cli.py user --url 'https://www.xiaohongshu.com/user/profile/xxxx?...' --resume |
| python cli.py search --query 榴莲 --num 50 --resume |
| ``` |
|
|
| 如需代理: |
|
|
| ```bash |
| python cli.py search --query 榴莲 --num 50 --proxy http://127.0.0.1:7890 |
| ``` |
|
|
| --- |
|
|
| ## 🧪 FastAPI 服务(对接 Java/任务系统) |
| - 适合场景:把 Spider_XHS 作为“采集/解析微服务”,由上游(Java/Agent/工作流引擎)提交任务并拉取结果;也可配置回调推送。 |
| - 提示:服务端不会要求你把 Cookie 写进代码;推荐通过环境变量或任务 payload 注入,且不要在日志中打印 Cookie。 |
| |
| ### 🚀 启动服务(uvicorn) |
| 在项目根目录执行: |
| |
| ```bash |
| python -m uvicorn Spider_XHS.service.app:app --host 0.0.0.0 --port 8000 |
| ``` |
| |
| 开发调试(热加载): |
| |
| ```bash |
| python -m uvicorn Spider_XHS.service.app:app --host 0.0.0.0 --port 8000 --reload |
| ``` |
| |
| 启动后: |
| - OpenAPI JSON:`http://localhost:8000/openapi.json` |
| - Swagger UI:`http://localhost:8000/docs` |
| |
| ### 🖥️ 运营控制台前端(frontend/) |
| `frontend/` 提供基于 Vite + React + TypeScript 的运营控制台,用于查看健康状态、任务中心、RPA 回传、错误中心、资源池中心、内容库与监控指标等能力。 |
| |
| 页面路由: |
| - `/dashboard`:服务健康概览 |
| - `/tasks`、`/tasks/:id`:任务中心与任务详情 |
| - `/rpa`:RPA 回传(Chrome 插件) |
| - `/errors`:错误中心 |
| - `/resources/accounts`、`/resources/sessions`、`/resources/proxies`:资源池中心(账号/会话/代理) |
| - `/content/raw-notes`、`/content/cleaned-notes`:内容库(原始笔记/清洗笔记) |
| - `/metrics`:监控指标 |
| |
| #### 1) 安装依赖 |
| ```bash |
| cd frontend |
| npm install |
| ``` |
| |
| #### 2) 配置后端地址(VITE_API_BASE_URL) |
| 默认后端地址为 `http://localhost:8000/api/v1`。如需调整,可通过环境变量覆盖: |
|
|
| - 推荐本地联调(走 Vite dev proxy,避免 CORS): |
| ```bash |
| export VITE_API_BASE_URL=/api/v1 |
| ``` |
|
|
| - 或指定完整地址(跨域访问,需后端允许 CORS): |
| ```bash |
| export VITE_API_BASE_URL=http://localhost:8000/api/v1 |
| ``` |
|
|
| #### 3) 启动前端(开发模式) |
| ```bash |
| npm run dev |
| ``` |
|
|
| 访问地址:`http://localhost:5173/` |
|
|
| #### 4) 与 FastAPI 同时启动(本地联调) |
| 终端 A(后端): |
| ```bash |
| python -m uvicorn Spider_XHS.service.app:app --host 0.0.0.0 --port 8000 --reload |
| ``` |
|
|
| 终端 B(前端): |
| ```bash |
| cd frontend |
| export VITE_API_BASE_URL=/api/v1 |
| npm run dev |
| ``` |
|
|
| ### 🧩 API 概览(/api/v1) |
| 服务默认只开放带版本前缀的接口(推荐): |
| - Base URL:`http://<host>:8000/api/v1` |
| - 统一响应包装:`{ "code": 200, "msg": "success", "data": ... }` |
| - 兼容旧路由(不带 `/api/v1`)可通过 `ENABLE_LEGACY_ROUTES=1` 打开,默认关闭 |
|
|
| #### 统一响应格式 |
| 所有接口(包括错误)均返回如下结构: |
|
|
| ```json |
| { |
| "code": 200, |
| "msg": "success", |
| "data": {} |
| } |
| ``` |
|
|
| 常用错误码(节选): |
| | 场景 | HTTP | code | 说明 | |
| |------|------|------|------| |
| | 鉴权/登录态失效 | 401 | 10001 | auth required | |
| | 单 IP 限流 | 429 | 10002 | rate limited | |
| | 风控/验证码 | 403 | 10003 | risk control | |
| | 参数/路径无效 | 400/404 | 10007 | invalid target | |
| | 任务不存在 | 404 | 10008 | task not found | |
| | 结果未就绪 | 409 | 10009 | task not ready | |
|
|
| #### 端点一览 |
| | 方法 | 路径 | 说明 | |
| |------|------|------| |
| | GET | `/tasks` | 分页查询任务列表(过滤/排序) | |
| | POST | `/tasks` | 创建任务 | |
| | GET | `/tasks/{task_id}` | 查询任务状态 | |
| | GET | `/tasks/{task_id}/result` | 获取任务结果 | |
| | POST | `/tasks/{task_id}/callback/retry` | 手动重试回调 | |
| | POST | `/import/excel` | Excel 导入 | |
| | POST | `/import/extension` | Chrome 插件回填 | |
| | GET | `/errors/summary` | 错误聚合统计与失败任务列表 | |
| | GET | `/resources/accounts` | 账号池快照(只读) | |
| | GET | `/resources/sessions` | 会话池轻量检查(只读) | |
| | GET | `/resources/proxies` | 代理池快照(只读) | |
| | GET | `/content/raw-notes` | 内容库 raw_note 列表(SQLite,只读) | |
| | GET | `/content/cleaned-notes` | 内容库 cleaned_note 列表(SQLite,只读) | |
| | GET | `/health` | 健康检查 | |
| | GET | `/metrics` | Prometheus 指标 | |
|
|
| #### 运维:GET /api/v1/health |
| 返回字段(节选): |
| - `queue_length`:当前 `queued` 任务数量 |
| - `engine_usage_counts`:各引擎累计处理任务数(内存计数器,随进程重启清零) |
| - `success_count` / `fail_count`:累计成功/失败任务数(内存计数器,随进程重启清零) |
| - `recent_failure_rate`:近期失败率(滑动窗口) |
| - `recent_failure_window_seconds` / `recent_failure_total` / `recent_failure_failed`:失败率窗口与分子分母 |
|
|
| #### 监控:GET /api/v1/metrics |
| Prometheus 文本格式(`text/plain; version=0.0.4`),核心指标(节选): |
| - `spider_xhs_queue_length` |
| - `spider_xhs_tasks_total{engine,status}` |
| - `spider_xhs_tasks_succeeded_total` / `spider_xhs_tasks_failed_total` |
| - `spider_xhs_recent_failure_rate` |
|
|
| #### 错误中心:GET /api/v1/errors/summary |
| 用途:聚合最近 N 条任务的 `error_kind` 分布,并返回失败任务列表(可分页/过滤)。 |
|
|
| Query 参数(节选): |
| - `scan_limit`:扫描最近任务数量(默认取 `ERROR_SUMMARY_SCAN_LIMIT`,未配置则 1000) |
| - `status`:逗号分隔过滤(例如 `failed,waiting_rpa`) |
| - `error_kind`:逗号分隔过滤(例如 `auth,rate`) |
|
|
| #### 资源池中心:GET /api/v1/resources/* |
| - `/resources/accounts`:账号池快照(risk_score/cooldown 等) |
| - `/resources/sessions`:会话池轻量检查结果(ok/reason) |
| - `/resources/proxies`:代理池快照(规模/均分/失败原因分布等) |
| |
| #### 内容库:GET /api/v1/content/* |
| 说明:内容库从编排层 SQLite 读取数据,数据库路径由 `ORCHESTRATOR_DB_PATH` 指定(默认 `orchestrator/data/mvp.db`)。 |
| |
| - `/content/raw-notes`:raw_note 列表(author/url/content 模糊搜索) |
| - `/content/cleaned-notes`:cleaned_note 列表(cleaned_content + 关联 raw_note 信息) |
| |
| #### 日志字段(结构化) |
| 服务日志会在 `extra` 中附带结构化字段(示例字段): |
| - `task_id` / `task_type` / `engine` / `status` |
| 不要把 Cookie、回调签名、Authorization 等敏感信息写入日志;错误信息会对 URL token/cookies 等做脱敏。 |
| |
| #### 1) 创建任务:POST /api/v1/tasks |
| 用途:提交一个采集/解析任务,立即返回 task_id,服务端后台执行。 |
|
|
| 请求体(JSON): |
| - `task_type`:`note_url` / `search` / `user_profile` |
| - `target`:采集目标(URL/关键词/用户ID),推荐使用;会自动写入 payload(向后兼容) |
| - `payload`:任务参数(见下方示例) |
| - `engine`:可选,`auto` / `api` / `browser`(不传则使用环境变量 `ENGINE_STRATEGY`) |
|
|
| 示例(抓取笔记详情): |
|
|
| ```bash |
| curl -X POST "http://localhost:8000/api/v1/tasks" \ |
| -H "Content-Type: application/json" \ |
| -d '{ |
| "task_type": "note_url", |
| "target": "https://www.xiaohongshu.com/explore/xxxx?xsec_token=yyyy", |
| "engine": "auto", |
| "payload": { |
| "operator": "demo" |
| } |
| }' |
| ``` |
|
|
| 说明: |
| - API 引擎(Spider_XHS)Cookie 来源优先级:`payload.cookies`/`payload.cookie`/`payload.cookies_str` > 环境变量 `COOKIES`/`XHS_COOKIES` |
| - 代理来源优先级:`payload.proxies`(对象)> `payload.proxy`/`payload.proxies`(字符串)> 环境变量 `SERVICE_PROXY`;浏览器引擎可额外配置 `SERVICE_PROXY_POOL` 做简单轮换 |
|
|
| 不同 task_type 的 payload 约定: |
| - `note_url` |
| - `note_url`:笔记链接(必填) |
| - `cookies`:可选(推荐从环境变量注入,避免透传到上游日志) |
| - `search` |
| - `query` 或 `keyword`:关键词(必填) |
| - `require_num` 或 `limit`:期望条数(默认 20) |
| - `sort_type_choice` / `note_type` / `note_time` / `note_range` / `pos_distance` / `geo`:可选(与 CLI/现有 API 对齐) |
| - `user_profile` |
| - `user_id` 或 `uid`:用户 id(必填其一) |
| - 或 `user_url`/`url`:用户主页链接(可由 URL 自动解析 user_id) |
| |
| #### 2) 查询任务状态:GET /api/v1/tasks/{task_id} |
|
|
| ```bash |
| curl "http://localhost:8000/api/v1/tasks/<task_id>" |
| ``` |
|
|
| 返回字段(节选): |
| - `task.status`:`queued` / `running` / `succeeded` / `failed` |
| - `task.engine`:实际执行引擎(例如 `spider_xhs` / `mediacrawler`) |
| - `task.callback`:回调状态(配置了回调才会出现) |
|
|
| #### 3) 获取任务结果:GET /api/v1/tasks/{task_id}/result |
| - 若任务仍在 `queued/running`,会返回 `409`(result not ready)。 |
| - 任务结束后返回: |
| - `raw`:引擎原始返回(结构可能随上游接口变化) |
| - `normalized`:标准化后的关键字段(便于入库/检索) |
| - `meta`:任务元信息与错误分类 |
| |
| ```bash |
| curl "http://localhost:8000/api/v1/tasks/<task_id>/result" |
| ``` |
| |
| `meta` 常用字段: |
| - `ok`:是否成功 |
| - `error_kind`:失败类型(如 `auth` / `rate` / `risk` / `parse` / `timeout` / `missing_dependency`) |
| - `primary_engine` / `final_engine`:自动策略下的主引擎与最终引擎 |
| - `fallback_reason`:触发兜底的原因(如阈值触发、鉴权/风控失败等) |
|
|
| #### 4) 回调失败手动重试:POST /api/v1/tasks/{task_id}/callback/retry |
| 仅当配置了回调地址且结果已生成时可用。服务端会: |
| - 使用 `Idempotency-Key` 请求头进行幂等控制 |
| - 最多尝试 5 次(指数退避 + 抖动) |
| - 若仍失败,会把失败请求落盘,供后续重试 |
| |
| ```bash |
| curl -X POST "http://localhost:8000/api/v1/tasks/<task_id>/callback/retry" |
| ``` |
| |
| #### 5) Excel 导入(人工兜底):POST /api/v1/import/excel |
| 用途:当线上采集受风控/验证码影响,可用人工导出的 Excel 进行导入与标准化。 |
| |
| 请求(multipart/form-data): |
| - `file`:Excel 文件 |
| - `operator`:操作者/来源标识(必填) |
| - `source_name`:可选,来源名称(如“运营同学A导出”) |
|
|
| ```bash |
| curl -X POST "http://localhost:8000/api/v1/import/excel" \ |
| -F "file=@/path/to/demo.xlsx" \ |
| -F "operator=ops" \ |
| -F "source_name=manual_export" |
| ``` |
|
|
| 模板识别(自动): |
| - `xhs_data_assistant`:命中“曝光/阅读/浏览/互动/转粉”等数据助手指标列,并同时包含“笔记标题/笔记链接/作者昵称”等识别列 |
| - `fixed_template`:兜底模板(任意表头),会尝试从行内提取 URL/关键词等信息 |
|
|
| `xhs_data_assistant` 支持的常见列(中英文均可,大小写/空格不敏感): |
| - 识别列:`笔记链接`/`笔记url`/`作品链接` → `note_url`,`笔记标题` → `title`,`作者昵称` → `author` |
| - 时间列:`发布时间`/`上传时间` → `publish_time` |
| - 互动指标:`点赞` → `like`,`评论` → `comment`,`收藏` → `collect`,`分享`/`转发` → `share` |
| - 流量指标:`曝光` → `exposure`,`阅读` → `read`,`浏览` → `view`,`互动` → `interact`,`转粉` → `follow` |
| - 内容类型:`内容类型`/`笔记类型` → `content_type` |
|
|
| 标准化输出(`records[].normalized`): |
| - 基础:`kind`(note/user/search/url)、`note_url`/`note_id`/`user_url`/`user_id`/`query` |
| - 补充:`title`、`author`/`nickname`、`publish_time`、`like_count`、`comment_count`、`collect_count`、`share_count`、`exposure`、`read`、`view`、`interact`、`follow`、`content_type` |
|
|
| 溯源信息(`records[].meta`): |
| - `import_id`、`operator`、`source_name`、`row_number`、`dedup_key`、`parser`、`filename`、`sheet` |
|
|
| ### ⚙️ 环境变量配置(建议仅在部署环境注入,不要写入代码/仓库) |
| > 下表仅展示变量名与用途;不要在日志/报错里输出真实 Cookie、回调签名、账号信息等敏感数据。 |
|
|
| | 变量 | 默认值 | 说明 | |
| |------|--------|------| |
| | `ENABLE_LEGACY_ROUTES` | `0` | 是否兼容旧接口(不带 `/api/v1` 前缀);建议生产关闭 | |
| | `STORAGE_ROOT` / `SERVICE_STORAGE_ROOT` / `SERVICE_STORAGE_DIR` | `./storage` | 服务落盘根目录(任务/结果/回调失败/原始快照/日志) | |
| | `SERVICE_CONCURRENCY` | `4` | 任务执行并发度(建议和上游并发一起收敛) | |
| | `SERVICE_PROXY` | 空 | 代理(同时影响 API 引擎与浏览器引擎) | |
| | `SERVICE_PROXY_POOL` | 空 | 代理池(逗号分隔多个代理,浏览器引擎按重试次数轮换;会与 `SERVICE_PROXY` 合并去重) | |
| | `ENGINE_STRATEGY` | `auto` | `auto`/`api`/`browser` | |
| | `ENGINE_FALLBACK_THRESHOLD` | `3` | `auto` 模式下切换浏览器引擎的失败阈值 | |
| | `RAW_DATA_RETENTION_DAYS` | `7` | 原始 HTML 快照保留天数(启动时清理 + 定时清理) | |
| | `ORCHESTRATOR_DB_PATH` | `orchestrator/data/mvp.db` | Orchestrator SQLite 路径(内容库接口 `/content/*` 读取,只读打开) | |
| | `ERROR_SUMMARY_SCAN_LIMIT` | `1000` | 错误中心默认扫描最近任务数(用于 `/errors/summary` 的默认 `scan_limit`) | |
| | `CALLBACK_URL` / `SERVICE_CALLBACK_URL` | 空 | 任务完成后回调推送地址(可选) | |
| | `MEDIACRAWLER_STORAGE_STATE_PATHS` | 空 | 浏览器引擎登录态文件路径(逗号分隔多个候选) | |
| | `MEDIACRAWLER_STORAGE_STATE_PATH` | 空 | 同上(单路径兼容) | |
| | `MEDIACRAWLER_MOCK` | `0` | 浏览器引擎 mock 模式(不依赖 Playwright,可用于自测/验证脚本) | |
| | `MEDIACRAWLER_RETRY_MAX` | `3` | 浏览器引擎页面访问重试次数(含首次) | |
| | `MEDIACRAWLER_RETRY_BASE_S` | `0.8` | 浏览器引擎重试指数退避基准秒数 | |
| | `MEDIACRAWLER_RETRY_CAP_S` | `12` | 浏览器引擎重试指数退避上限秒数 | |
| | `MEDIACRAWLER_DELAY_MIN_S` | `0.4` | 浏览器引擎随机延迟下限(秒) | |
| | `MEDIACRAWLER_DELAY_MAX_S` | `1.2` | 浏览器引擎随机延迟上限(秒) | |
| | `COOKIES` / `XHS_COOKIES` | 空 | API 引擎登录 Cookie(敏感:建议仅在服务侧注入,不要写入镜像/仓库) | |
| | `LOG_LEVEL` | `INFO` | 日志级别 | |
| | `LOG_ROTATION` | `1 day` | 日志切分策略(loguru rotation) | |
| | `LOG_RETENTION` | `14 days` | 日志保留策略(loguru retention) | |
| | `LOG_COMPRESSION` | `zip` | 压缩策略(loguru compression) | |
|
|
| `MEDIACRAWLER_STORAGE_STATE_PATHS` 示例: |
|
|
| ```bash |
| export MEDIACRAWLER_STORAGE_STATE_PATHS="/data/xhs/storage_state.json,/app/datas/state.json" |
| ``` |
|
|
| ### 🐳 Docker Compose 部署(推荐) |
| 项目根目录已提供 `docker-compose.yml`,默认把宿主机 `./storage` 挂载到容器 `/app/storage`: |
|
|
| ```bash |
| docker compose up -d --build |
| ``` |
|
|
| 建议做法: |
| - 使用单独的环境文件(例如 `.env.local`)注入 `COOKIES`/`CALLBACK_URL` 等敏感变量,并确保不提交到仓库 |
| - 生产环境用反向代理(Nginx/Traefik)提供 TLS,并设置 `x-forwarded-for` 以获得真实 IP(限流按 IP 生效) |
|
|
| ### ☕ Java 对接示例 |
| #### 模式 A:拉取(推荐,最简单稳定) |
| 流程: |
| 1) Java 调用 `POST /api/v1/tasks` 创建任务拿到 task_id |
| 2) Java 轮询 `GET /api/v1/tasks/{task_id}` 或直接轮询 `GET /api/v1/tasks/{task_id}/result` |
| 3) 拿到 `normalized/meta` 入库;`raw` 可按需归档 |
| |
| OkHttp 示例(精简版): |
| |
| ```java |
| import okhttp3.*; |
| import java.util.concurrent.TimeUnit; |
| |
| public class SpiderXhsClient { |
| private final OkHttpClient http = new OkHttpClient.Builder() |
| .connectTimeout(5, TimeUnit.SECONDS) |
| .readTimeout(30, TimeUnit.SECONDS) |
| .build(); |
| |
| public String createTask(String baseUrl, String noteUrl) throws Exception { |
| String json = "{" |
| + "\"task_type\":\"note_url\"," |
| + "\"engine\":\"auto\"," |
| + "\"payload\":{\"note_url\":\"" + noteUrl + "\",\"operator\":\"java\"}" |
| + "}"; |
| Request req = new Request.Builder() |
| .url(baseUrl + "/api/v1/tasks") |
| .post(RequestBody.create(json, MediaType.parse("application/json"))) |
| .build(); |
| try (Response resp = http.newCall(req).execute()) { |
| if (!resp.isSuccessful()) throw new RuntimeException("createTask http=" + resp.code()); |
| return resp.body().string(); |
| } |
| } |
| } |
| ``` |
| |
| 生产环境请解析 JSON 响应,读取 `task.id` 作为 task_id。 |
| |
| 建议: |
| - `GET /tasks/{task_id}/result` 返回 409 时,说明结果未就绪;可退避重试(例如 0.5s/1s/2s 递增)。 |
| - 如果 `meta.ok=false` 且 `meta.error_kind=risk/auth`,通常需要人工处理验证码或更新 Cookie/登录态。 |
|
|
| #### 模式 B:回调推送(可选) |
| 配置: |
| - 在 Spider_XHS 服务侧设置 `CALLBACK_URL`(或 `SERVICE_CALLBACK_URL`) |
|
|
| 回调行为: |
| - 服务完成任务后会 `POST CALLBACK_URL` |
| - 请求头:`Idempotency-Key: <sha256>` |
| - 请求体:`{"task_id":"...","result":{...}}` |
|
|
| Spring Boot 接收示例(示意,需自行实现幂等去重存储): |
|
|
| ```java |
| import org.springframework.web.bind.annotation.*; |
| import java.util.Map; |
| |
| @RestController |
| public class SpiderXhsCallbackController { |
| @PostMapping("/spider-xhs/callback") |
| public Map<String, Object> callback( |
| @RequestHeader(value = "Idempotency-Key", required = false) String idemKey, |
| @RequestBody Map<String, Object> body |
| ) { |
| return Map.of("ok", true); |
| } |
| } |
| ``` |
|
|
| 生产环境建议使用 `Idempotency-Key` 做幂等去重(例如落库或 Redis SETNX),同时避免把任何敏感字段写入日志。 |
|
|
| 回调失败处理: |
| - 服务会自动重试(最多 5 次),仍失败会落盘记录 |
| - 上游可调用 `POST /api/v1/tasks/{task_id}/callback/retry` 触发再次推送 |
|
|
| ### 🛡️ 风控/验证码/封号风险建议(务必阅读) |
| - 限速:控制 QPS 与随机抖动(尤其是搜索/批量详情),避免固定频率与高峰期密集请求。 |
| - 并发:客户端线程数与服务端并发同时收敛;建议从小并发开始(例如 1~3)逐步压测。 |
| - 代理:优先稳定的住宅/独享代理;按账号/会话做粘性,避免频繁切换出口;异常时再切换。 |
| - 人工验证码:当出现验证码/风控(`meta.error_kind=risk/auth`),建议人工在浏览器完成验证并更新 Cookie 或 Playwright storage_state。 |
| - 账号隔离:不同业务/环境使用不同账号与独立存储目录;避免共享 Cookie 造成互相踢下线。 |
| |
| ### 🧰 运维说明(日志/清理/迁移) |
| - 日志目录:`<STORAGE_ROOT>/logs/`,默认文件 `service.log`(按 `LOG_ROTATION` 轮转,保留 `LOG_RETENTION`,按需压缩) |
| - 原始快照:浏览器引擎可能会将 HTML 快照写入 `<STORAGE_ROOT>/raw/`,由 `RAW_DATA_RETENTION_DAYS` 控制保留天数(启动时清理 + 定时清理) |
| - 存储迁移:若检测到旧版 `tasks.json`,服务启动时会自动迁移到 `<STORAGE_ROOT>/tasks/{task_id}.json`,并将旧文件重命名为 `tasks.json.migrated` |
| - 备份建议:按目录整体备份 `<STORAGE_ROOT>` 即可(包含任务、结果、回调失败、快照与日志) |
|
|
| ### ✅ 合规红线(务必遵守) |
| - 仅在获得授权、符合平台协议与当地法律法规前提下使用本项目 |
| - 不要采集/存储/传播敏感个人信息,避免长期留存可识别数据(PII) |
| - Cookie、storage_state、回调签名等属于敏感凭证,严禁写入仓库、镜像、公开日志与错误回传 |
| - 如需留存数据,建议最小化采集字段、设置保留期、建立审计与删除机制 |
| |
| --- |
| |
| ## 📁 项目结构 |
| |
| ``` |
| Spider_XHS/ |
| ├── main.py # 主入口:爬虫调用示例 |
| ├── apis/ |
| │ ├── xhs_pc_apis.py # 小红书PC端完整API(采集) |
| │ ├── xhs_creator_apis.py # 创作者平台API(上传发布) |
| │ ├── xhs_pc_login_apis.py # PC端登录(二维码/手机验证码) |
| │ ├── xhs_creator_login_apis.py # 创作者平台登录 |
| │ ├── xhs_pugongying_apis.py # 蒲公英平台API(KOL数据) |
| │ └── xhs_qianfan_apis.py # 千帆平台API(分销商数据) |
| ├── xhs_utils/ |
| │ ├── common_util.py # 初始化工具(读取.env配置) |
| │ ├── cookie_util.py # Cookie解析 |
| │ ├── data_util.py # 数据处理(Excel保存、媒体下载) |
| │ ├── xhs_util.py # PC端签名算法封装 |
| │ ├── xhs_creator_util.py # 创作者平台签名算法封装 |
| │ ├── xhs_pugongying_util.py # 蒲公英平台工具 |
| │ └── xhs_qianfan_util.py # 千帆平台工具 |
| ├── static/ |
| │ ├── xhs_main_260411.js # PC端签名核心JS(最新版) |
| │ ├── xhs_creator_260411.js # 创作者平台签名核心JS(最新版) |
| │ └── ... |
| ├── .env # Cookie配置(不要提交到git) |
| ├── requirements.txt |
| ├── Dockerfile |
| └── package.json |
| ``` |
| |
| --- |
| |
| ## 🗝️ 注意事项 |
| |
| - `main.py` 是爬虫入口,可根据需求修改调用逻辑 |
| - `apis/xhs_pc_apis.py` 包含所有 PC 端数据接口 |
| - `apis/xhs_creator_apis.py` 包含创作者平台发布接口 |
| - Cookie 有时效性,失效后需重新获取 |
| - 建议配合代理(proxies 参数)使用,降低封号风险 |
| |
| --- |
| |
| ## 🍥 更新日志 |
| |
| | 日期 | 说明 | |
| |------|------| |
| | 23/08/09 | 首次提交 | |
| | 23/09/13 | API 更改 params 增加两个字段,修复图片无法下载,修复部分页面无法访问报错 | |
| | 23/09/16 | 修复较大视频编码问题,加入异常处理 | |
| | 23/09/18 | 代码重构,加入失败重试 | |
| | 23/09/19 | 新增下载搜索结果功能 | |
| | 23/10/05 | 新增跳过已下载功能,获取更详细的笔记和用户信息 | |
| | 23/10/08 | 上传至 PyPI,可通过 pip install 安装 | |
| | 23/10/17 | 搜索下载新增排序方式(综合 / 热门 / 最新) | |
| | 23/10/21 | 新增图形化界面,上传至 release v2.1.0 | |
| | 23/10/28 | Fix Bug:修复搜索功能隐藏问题 | |
| | 25/03/18 | 更新 API,修复部分问题 | |
| | 25/06/07 | 更新 search 接口,区分视频和图集下载,新增创作者平台 API | |
| | 25/07/15 | 更新 xs version56 & 小红书创作者接口 | |
| | 26/04/11 | 重构创作者平台 API(图集 / 视频上传),新增蒲公英 KOL 数据 API,新增千帆分销商 API,签名算法升级至最新版 | |
| | 26/04/16 | **架构升级**:全面升级为“稳定性大脑 + 双自动引擎 + RPA 回传兜底”架构(Spider_XHS + MediaCrawler兜底 + Extension 回传),新增 FastAPI 微服务、Webhook 回调、数据助手 Excel 解析、Prometheus 监控与 IP 级限流机制 | |
| | 26/04/16 | **业务闭环(样例级)**:新增 `orchestrator` 编排层,基于 SQLite 搭建 14 张核心业务表,提供“采集同步 -> 基础清洗 -> Mock 飞书同步/告警落库”的最小闭环样例 | |
| | 26/04/16 | **稳定性增强**:引入 **Stability Controller** 大脑与资源池(Account/Session/Proxy Pool),升级为**双自动引擎 + RPA 回传兜底**,增强浏览器引擎拟人化 Stealth,任务状态机升级为多阶段容灾流转 | |
| | 26/04/16 | **可视化控制台**:新增基于 React + Vite 的前端可视化看板,落地资源池中心(账号/会话/代理状态)、错误中心(失败任务聚合分析)与内容库基础页的可视化闭环 | |
|
|
| --- |
|
|
| ## 🧸 额外说明 |
|
|
| 1. 欢迎 PR 和 Issue。 |
| 2. 项目会持续更新,致力于提供更稳定的数据采集服务。 |
|
|