DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

BaxterL /

BaxterL/dsh-xhs-search

Verified

Xiaohongshu (???/RED) reader for DeepSeek Harness: CDP-driven isolated browser, real-input click opening, DOM-only extraction, local knowledge base. Zero runtime dependencies.

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHubProject homepage
READMESource: main@d5c51bc8

dsh-xhs-search

给 DeepSeek Harness 的小红书阅读器:搜索、点开、读完一篇笔记,正文和评论落进本地知识库。

dsh-xhs-search

装完之后,任何会话里说一句「帮我看看小红书上的 xxx」,模型就会调用 xhs 工具: 拿整屏卡片、点开正文、抓评论、存本地。

零运行时依赖。 不需要 playwright,不需要 puppeteer,不需要 ws——只有 Node ≥ 22.5 的内置 WebSocket 和 fetch。


为什么不是又一个爬虫

小红书的 Web 端能认出自动化。这个工具把四个坑封死在实现里,而不是写在提示词里:

坑 表现 这里的做法
直接跳笔记 URL 安全限制 300013 / error_code=300031,整个标签页被重定向,之后连搜索都失效 只点搜索页的卡片;卡片不在 DOM 里就报 card-not-in-dom,绝不降级成跳 URL
CDP 合成点击 前几次能用,很快被识别 → 安全限制 / 验证码 Windows 上走 SetCursorPos + mouse_event 的硬件点击;没有校准时退回 CDP 并明确告诉你降级了
详情接口 /api/sns/web/v1/feed 一律 500 正文和评论只从 DOM 读
封面格式 URL 写着 .jpg,字节其实是 WebP,Word/PDF 不认 按魔数嗅探,非 JPEG/PNG 用 Pillow 转码

还有一个别人不太提的:详情浮层是"先挂载、后填数据"的。 刚点开的那几百毫秒里标题是空的、点赞数还显示「赞」。这时候读会得到一篇没有正文、没有数字的"成功"笔记—— 比失败更糟。所以读之前会轮询到浮层真的填好为止。


装

// ~/.dsh/profiles/desktop/package.json
{
  "dependencies": {
    "dsh-xhs-search": "^0.1.0"
  },
  "dsh": { "profile": { "bundles": ["dsh-xhs-search"] } }
}

然后完全退出 DSH(含托盘图标)再打开。

装完不会自己开浏览器——第一次调用工具才启动。窗口是独立的 --user-data-dir, 和你日常浏览器完全隔离,登录态存在里面。

首次三步

npx xhs-search launch      # 起窗口;第一次在这个窗口里扫码登录
npx xhs-search calibrate   # 校准视口原点,硬件点击才落得准
npx xhs-search status      # 确认登录成功、没有限流、没有验证码

校准只需要做一次。窗口被移动过要重做,否则点击会落偏。


用

工具名 xhs,一个 action 一次调用:

action 做什么
search 搜索,返回整屏卡片:标题 / 作者 / 赞藏评 / 封面 / 相对时间
read 从当前搜索页点开一篇,返回正文、话题、配图、最多 60 条评论
harvest 搜完直接开最新的 N 篇,自动入库
notes / note 只读本地知识库,零联网、零风控成本
status 登录门 / 限流 / 验证码 / 本轮预算
limits 现在能不能开下一篇,还要等多久
config 路径与配置

命令行是同一套实现,方便人手调:

npx xhs-search search "应援物料" --limit 10
npx xhs-search read 6a9b80c3000000002601fb09
npx xhs-search harvest "追星 物料" --limit 5 --max-age 72
npx xhs-search notes "教程"

限速

平台按账号频次限流,和"是不是真人点击"无关。慢就是快。

项 默认
两篇笔记之间 25 秒
每小时上限 60 篇
前 2 篇 双倍间隔(热身)
触发限制后的降温 20 分钟 × 2^(strikes-1),最长 1 小时上限

这些不是建议,是 guard.ts 里的门。xhs limits 说不能开就别开—— 绕过它不会更快,只会把「慢一次」变成「封一段」。

三种状态要分清:

  • login gate — 登录态失效。请人在那个窗口扫码。
  • rate limit — 详情被限流。停手,搜索还能用。
  • captcha — 弹验证码了。只有人能过,任何自动点击都会加重风控。

知识库

默认 ~/Desktop/xhs/:

xhs/
├── browser-profile/     隔离窗口的登录态
├── osinput-cal.json     视口校准
├── kb/
│   ├── notes.json       笔记:正文 / 作者 / 时间 / 赞藏评 / 话题 / 配图 / 评论
│   ├── searches.json    每次检索记录
│   ├── guard.json       限速状态(重启也记得)
│   └── img/             配图,<笔记ID>-01.jpg
└── reports/             留给下游的汇总

notes.json 是原子写:先写临时文件再改名,崩溃不会留下半个文件。 重复读同一篇会合并评论和配图(浮层只渲染第一屏评论,第二次读能看到更多), 但 firstSeen 保留最早那次。

环境变量:XHS_WORKSPACE XHS_BROWSER XHS_PORT XHS_REAL_INPUT XHS_PYTHON XHS_DETAIL_GAP_MS XHS_SEARCH_GAP_MS XHS_MAX_DETAILS_PER_HOUR XHS_BLOCK_COOLDOWN_MS。


结构

src/
├── types.ts     共享类型
├── config.ts    路径与限速的解析
├── cdp.ts       极小 CDP 客户端(内置 WebSocket/fetch)
├── browser.ts   拉起隔离窗口
├── osinput.ts   Win32 硬件点击 + 自校验校准
├── extract.ts   页面脚本(字符串)与纯解析
├── guard.ts     限速与熔断,持久化
├── store.ts     知识库,原子写、合并
├── images.ts    魔数嗅探 + WebP 转码
├── session.ts   领域层:搜索 / 阅读 / 批量
├── tool.ts      模型看到的 xhs 工具
├── cli.ts       人手用的命令行
└── index.ts     插件入口

规则写在领域层而不是提示词里——模型不需要记住,也就没法绕回去。


测试

npm test        # 27 个用例:纯逻辑 + 用假 ctx 驱动 apply()

boot.test.mjs 用假 context 跑 apply(),验证:注册一个工具、一个提示词段落、 一个占位符全部替换掉的技能正文,并且启动插件不会开浏览器。


平台

Windows 用于硬件点击(user32.dll)。macOS / Linux 也能跑,但会退回 CDP 合成点击, 风控风险明显更高,read 会明确报 opened by: cdp。

浏览器要 Chromium 系(Edge / Chrome / Brave),Node ≥ 22.5。


红线

  • 只读:搜索、读笔记、读评论。不点赞、不评论、不关注、不发帖、不私信。
  • 限速:用默认值。高频批量抓取会触发风控,也可能违反平台条款。
  • 范围:只处理你有权访问的公开内容;登录态属于你本人,不要导出或分享 cookie。
  • 署名:整理内容对外发布时,注明信息来自小红书用户,尊重原作者。

License

MIT

—/ 5

No ratings yet

Verified DSH bundle

Commit d5c51bc896e6

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout