ワンクリックで
js-xiaohongshu-ops-skill
小红书内容读取 skill,提供笔记详情、评论、搜索、用户主页等多 profile READ + 受控 INTERACTIVE 导航能力。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
小红书内容读取 skill,提供笔记详情、评论、搜索、用户主页等多 profile READ + 受控 INTERACTIVE 导航能力。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Install, configure, verify, and troubleshoot JS Eyes browser automation for OpenClaw.
Bilibili 视频读取 skill,提供视频元数据与字幕读取能力。
GitHub 仓库与 Issues 只读 + 浏览器导航 skill(REST + PAGE_PROFILES + bridges)。
Hacker News 只读 + 浏览器导航 skill:首页 / 帖子评论 / 用户 / Algolia 搜索走 Firebase API + DOM 兜底,浏览器侧仅 location.assign 改 URL。
Reddit 内容只读 + 浏览器导航 skill:帖子详情 / subreddit 列表 / 搜索 / 用户主页 / 收件箱 / 主 feed,DOM/API 双模式(auto 默认 DOM 优先 fallback API),浏览器侧仅 location.assign 改 URL。
X.com (Twitter) 内容只读 + 浏览器导航 + 账号监控 skill:搜索 / 用户主页 / 推文详情 / 首页 Feed 走 X.com 内部 GraphQL 同源端点(DOM 兜底),浏览器侧仅 location.assign 改 URL;内置 monitor 子系统做定时监控 + webhook 通知;写操作(reply/post/quote/thread)保持 v2.0.1 透传,v3.1 将拆到专用工具。
| name | js-xiaohongshu-ops-skill |
| description | 小红书内容读取 skill,提供笔记详情、评论、搜索、用户主页等多 profile READ + 受控 INTERACTIVE 导航能力。 |
| version | 3.0.0 |
| metadata | {"openclaw":{"emoji":"🌸","homepage":"https://github.com/imjszhang/js-eyes","requires":{"bins":["node"]}}} |
面向小红书内容读取的 skill。v2.1 起按 skills/js-x-ops-skill 的 PAGE_PROFILES + Bridges + Session 架构重构,支持笔记 / 搜索 / 用户 / 首页四个 profile,并按 v2.1 → v3.x 阶段渐进交付:
note-bridge 与 xhs_get_note / xhs_get_note_comments / xhs_session_state 三个 READ 工具。search-bridge + xhs_search_notes + 4 个 INTERACTIVE 导航工具)。user-bridge + xhs_get_user / xhs_get_user_notes)。xhs_get_note、xhs_get_note_comments、xhs_session_state(v2.1)。xhs_navigate_*(v2.2 起)。仅 location.assign,不模拟点击、不改 DOM。xhs_get_note 默认 readMode='auto',与 X 取反:
auto:DOM 优先 → API 兜底(小红书 DOM 覆盖更广,feed JSON 不稳定)。dom:仅 DOM 抽取。api:仅 API(笔记详情 stub,主用于评论/调试)。xhs_get_note_comments 默认 readMode='api'(基于 edith /api/sns/web/v2/comment/page,分页稳定)。
| 工具 | 类型 | 说明 |
|---|---|---|
xhs_get_note | READ | 笔记详情 + 可选评论 |
xhs_get_note_comments | READ | 评论分页(API 主路径) |
xhs_session_state | READ | 登录态读取(cookie a1/web_session + DOM 昵称) |
xhs_search_notes | READ | 搜索(频道 / 筛选 / 滚动;可 extractDetails 串行点开详情) |
xhs_get_user | READ | 用户主页资料(昵称、签名、关注/粉丝/获赞) |
xhs_get_user_notes | READ | 用户笔记列表(滚动分页) |
xhs_navigate_* | INTERACTIVE | navigate-note / search / user / home(仅 location.assign) |
xhs_monitor_list_targets | READ | 列出 monitor accounts + searches + channels |
xhs_monitor_get_status | READ | daemon pid + 各 target lastCheck/notesCount |
xhs_monitor_add_target | READ | 增加一个 user/search target(仅写 config,不发通知) |
xhs_monitor_remove_target | READ | 删除一个 user/search target |
xhs_monitor_test_target | READ | 单 target dry run(不写 state、不发通知) |
monitor 红线:
monitor init/monitor check/monitor daemon/monitor stop会触发 webhook,仅 CLI 暴露,不进 AI 工具列表。
# 初始化默认 config
node skills/js-xiaohongshu-ops-skill/index.js monitor init
# 添加用户监控 / 关键词监控
node skills/js-xiaohongshu-ops-skill/index.js monitor add user <userId>
node skills/js-xiaohongshu-ops-skill/index.js monitor add search "穿搭" --channel-type 图文
# 同步跑一次完整 check(会发 webhook)
node skills/js-xiaohongshu-ops-skill/index.js monitor check --pretty
# 启动循环 daemon
node skills/js-xiaohongshu-ops-skill/index.js monitor daemon --interval 1800
node skills/js-xiaohongshu-ops-skill/index.js monitor stop
# 状态
node skills/js-xiaohongshu-ops-skill/index.js monitor status --pretty
支持 feishu / discord / generic_webhook / console 4 种通知渠道,schema 在 ~/.js-eyes/skill-data/js-xiaohongshu-ops-skill/monitor/config.json,可由 JS_XHS_MONITOR_HOME 覆盖。
| xhs_navigate_note | INTERACTIVE | 仅 location.assign 导航到笔记详情 |
| xhs_navigate_search | INTERACTIVE | 仅 location.assign 导航到搜索页 |
| xhs_navigate_user | INTERACTIVE | 仅 location.assign 导航到用户主页 |
| xhs_navigate_home | INTERACTIVE | 仅 location.assign 导航到探索流首页 |
# 笔记详情(含评论)
node skills/js-xiaohongshu-ops-skill/index.js note "https://www.xiaohongshu.com/explore/xxxx" --with-comments --max-comment-pages 2 --pretty
# 评论分页
node skills/js-xiaohongshu-ops-skill/index.js comments "https://www.xiaohongshu.com/explore/xxxx" --max-comment-pages 5 --pretty
# 登录态
node skills/js-xiaohongshu-ops-skill/index.js session-state --pretty
# Doctor(4 profile 一站诊断)
node skills/js-xiaohongshu-ops-skill/index.js doctor --pretty
# 老路径 fallback(关闭 bridge)
JS_XHS_DISABLE_BRIDGE=1 node skills/js-xiaohongshu-ops-skill/index.js note "https://www.xiaohongshu.com/explore/xxxx"
xhs_search_notes(v3.9,注入 + 串行详情 + visual HUD + type / publishTime + 「大家都在搜」相关搜索词 + 联想词 best-effort)UI 路径与 agent-js DeepSearchWorkflow/lib/mcp/tools/xhsSearch.js 对齐;xhs 实际是 Vue(不是 React),且 visual-bridge-kit 会装 HP overlay,所有 click 都需绕开 [data-hp-installed] 优选 [data-hp-bound] 真节点。
| 阶段 | 选择器 / 行为 |
|---|---|
| 频道 Tab | #channel-container 内优先 [data-hp-bound]、按文本(全部 / 图文 / 视频 / 用户)匹配;fallback 跳过 [data-hp-installed] 的 HP overlay |
| 打开筛选面板 | 点击 textContent==='筛选' 的 span → 等 .filters-wrapper 出现 |
| 筛选选项 | 在 .filters-wrapper > .filters 行(按 title 文本「排序依据/笔记类型/发布时间/搜索范围」定位)→ 在 .tag-container .tags[data-hp-bound] 中按选项文本严格匹配 → click → 等 [data-hp-bound].active 切到目标值(appliedFilters.<group>_activated=false 暴露未真切的情况) |
| 关闭面板 | document.body.click() + 等 .feeds-container .note-item 重出现 |
| 滚动收集 | .feeds-container section.note-item 去重(noteId) |
| 详情串行 | 当 extractDetails=true:找带 xsec_token= 的 sibling <a> 点开 → 等 #noteContainer 或 .note-container → 等 .engage-bar .like-wrapper(防 stats/img lazyload 漏抓)→ 内联抽 → 路由模式 history.back() / 模态点 .close-circle .close → 等列表重现 |
| Visual | CLI 默认开(与 js-x-ops-skill 对齐):bridge 在切频道 / 打开筛选面板 / 每个筛选项 / 每条详情(点开 → 等互动栏 → 抽完 → 回列表)共 ~22 次 HUD pending/success + 17 次元素 flash,覆盖整个 19s 串行详情流程,无中段空白;--no-visual 关闭;--visual-record 才落帧;--visual-trace 智能 eat(下个参数以 - 开头视作 truthy)。监控不传 visualConfig,自动 noop |
参数
# 基本搜索(仅卡片列表)
node skills/js-xiaohongshu-ops-skill/index.js search "美食" --limit 10 --pretty
# 选排序 + 内容类型(sortBy 合法值:综合/最新/最多点赞/最多评论/最多收藏)
node skills/js-xiaohongshu-ops-skill/index.js search "美食" --sort-by 最多点赞 --content-type 图文 --time-range 一周内 --pretty
# 串行点开前 3 条详情(同 tab + back)
node skills/js-xiaohongshu-ops-skill/index.js search "美食" --limit 5 --extract-details --details-limit 3 --pretty
# 额外采集搜索框下拉联想词(best-effort,+6.5s;xhs 当前多数返回空,看 suggestKeywordsAttempt.error)
node skills/js-xiaohongshu-ops-skill/index.js search "美食" --limit 5 --collect-suggest --pretty
返回结构
notes[i]:卡片层除 noteId / url / title / author / likeCount / cover / xsec_token 外,新增 type: 'video' | 'normal'(按 a.cover .play-icon 判定)。notes[i].detail:当 extractDetails=true 且本条点开成功时含 { ok:true, title, description, content, image_urls, stats, author, publishTime, publishLocation, ... };publishTime 形如 刚刚 / 3天前 / 昨天 12:31 / 04-22 / 编辑于 2024-12-01;publishLocation 形如 上海 / 福建 / 意大利(无则 null)。失败时 { ok:false, error: 'card_anchor_not_found' | 'no_note_container' | 'route_navigated' | 'click_failed' },不会中断主流程。details: { requested, succeeded, failed }:详情统计;extractDetails=false 时为 null。appliedFilters: { channelType, sortBy, contentType, timeRange, searchScope, *_error? }:UI 真实落到的值;某筛选项失败仅写 <group>_error,主流程继续。filterPanelUsed:是否实际打开了筛选面板(无任何筛选项时 false)。relatedSearchKeywords: string[]:「大家都在搜」相关搜索词(拍平、去重;穿插在 feed 里的 .query-note-wrapper 块中收集,深度调研用)。relatedSearch: [{ header, words }]:按 header 分组的原始结构(同一 keyword 翻 30 条会出现 2 组,每组 4 个词)。suggestKeywords: string[]:搜索框下拉联想词。需 --collect-suggest (collectSuggest:true) 显式开启,开启后会增加 ~6.5s 耗时。实测 xhs 当前对 programmatic input.click()/focus() 严格 gating(要求 event.isTrusted),模拟事件 + InputEvent 全套都拿不到 popup → 多数情况返回 []。仅当浏览器是真用户在前台键盘操作时才能成功。suggestKeywordsAttempt: { keywords, hitSelector, durationMs, error }:联想词采集尝试的元数据,error: 'no_dropdown_visible' / 'no_input' 帮助调用方区分「试了拿不到」vs「根本没试」。注意
extractDetails 开销显著,建议 detailsLimit ≤ 10;硬上限 20。history.back 并把 detail.error: route_navigated 透出,不破坏主路径。searches[] 默认 extractDetails=false(长跑保守);可在 monitor config 的 search 项里显式 "extractDetails": true, "detailsLimit": 5 启用,monitor 内部会把 timeoutMs 自动从 240s 上调到 360s。小红书评论 API(/api/sns/web/v2/comment/page 等)必须有登录态,否则会回 code:300011 "Account abnormal"。skill 在两处做了门控:
runTool 在调用 xhs_get_note_comments 或 args.withComments===true 时,会先调一次 sessionState,若 cookieFlags.hasWebSession === false 则直接短路返回 error: 'login_required' + loginUrl: 'https://www.xiaohongshu.com/login',避免无谓打扰风控。api_getComments 自身也会再校验一次,返回 login_required 与 loginUrl,便于 AI/上游识别。CLI 提供 xhs login 引导子命令(仅 CLI,不暴露给 AI):
# 引导登录:打开登录页 + 轮询 web_session cookie 出现(默认最多 5 分钟)
node skills/js-xiaohongshu-ops-skill/index.js login --pretty
node skills/js-xiaohongshu-ops-skill/index.js login --timeout-ms 600000 --pretty
成功后输出 { ok:true, cookieFlags:{ hasWebSession:true, ... }, elapsedMs },超时则 { ok:false, error:'login_timeout' }。
每次 READ 工具跑完会把 history 行 append 到 ~/.js-eyes/skill-data/<skillId>/history/<YYYY-MM>.jsonl,cache 与 debug bundle 同目录其它子目录。runReadTool 会在 stderr 输出一行提示(除非加了 --quiet):
[xhs] records: /Users/x/.js-eyes/skill-data/.../history/2026-05.jsonl (notes=20)
result 顶层 run.paths.{historyFile,historyDir,cacheDir,debugDir} 也包含完整路径,便于上游脚本/AI 直接定位。
CLI 提供 xhs records 子命令快速查看最近的 records:
node skills/js-xiaohongshu-ops-skill/index.js records --last 5 --pretty
node skills/js-xiaohongshu-ops-skill/index.js records --tool xhs_get_note --last 10 --pretty
输出每条包含:run_id / tool / timestamp / status / duration_ms / cache_hit / input(摘要) / error / debugBundlePath。
每次 READ 工具返回顶层包含:
triedMethods – 尝试过的 bridge 方法序列(如 ['dom_getNote','api_getNote'])。usedMethod – 最终用了哪个 bridge 方法。readMode – 'dom' / 'api'。requestedReadMode – 调用方传入的 readMode('auto' / 'dom' / 'api')。fallback – 是否触发跨档位回退。antiCrawlState – { paused, pauseUntil, consecutiveRiskHits },由 bridge 共享。完整接入 @js-eyes/visual-bridge-kit(与 @skills/js-x-ops-skill 等价):bridge 内核装 window.__jse_visual,runTool 用 wrapCallApi + drainVisualEvents,工具粒度 hint 由 lib/visualHint.js 提供,可选写 trace JSONL + JPEG 帧序列 + visual session bundle 给 hyperframes 等下游消费。
--visual / --no-visual:总开关。--visual-hud / --no-visual-hud:右上角 HUD 卡片。--visual-flash / --no-visual-flash:元素 flash overlay。--visual-trace [path]:单文件 JSONL trace;不传 path 时落到默认 visualDir。--visual-record [dir]:完整 session bundle(events.jsonl + meta.json + JPEG 帧序列)。--visual-flash-ms / --visual-linger-ms / --visual-pinned-hold / --visual-error-pin / --visual-list-stride / --visual-prefix,详见 @js-eyes/visual-bridge-kit/node/visualConfig.js::DEFAULTS。--visual-mode(v0.6 拆成 hud/flash)、--visual-ms(v0.7 改名 --visual-flash-ms)。被 parseVisualFlags 检出后 stderr 一次性告警。~/.js-eyes/skill-data/js-xiaohongshu-ops-skill/visual/<runId>/(与 history/cache/debug 同级)。<visualDir>/trace.jsonl:所有 drain 出的 events 一行一条 JSON(type/ts/anchor/payload …)。<visualDir>/events.jsonl + <visualDir>/meta.json:visual session bundle。<visualDir>/frame-*.jpg:开 --visual-record 后才生成(与 events.jsonl/meta.json 同目录),每次 callApi 边界一帧(默认上限 60 帧、quality 82,hyperframes 默认在同目录找帧)。跑完后 stderr 输出一行 [xhs] visual: <path> (events=N),与 records 路径并列。
{
"visual": {
"enabled": true,
"hint": { "kind": "item", "toolName": "xhs_get_note", "label": "笔记 · ...", "anchor": { "noteId": "..." } },
"events": [/* drain 出的 emit 事件 */],
"eventsCount": 12,
"traceFile": ".../visual/<runId>/trace.jsonl",
"recordDir": ".../visual/<runId>",
"framesEnabled": true
}
}
# 1) HUD + flash 高亮
node skills/js-xiaohongshu-ops-skill/index.js note "https://www.xiaohongshu.com/explore/<id>?xsec_token=..." \
--visual --visual-hud --visual-flash --pretty
# 2) trace JSONL(默认目录)
node skills/js-xiaohongshu-ops-skill/index.js note "<url>" --visual --visual-trace --pretty
# → tail -1 ~/.js-eyes/skill-data/.../visual/<runId>/trace.jsonl
# 3) 完整录制(含 JPEG 帧序列)
node skills/js-xiaohongshu-ops-skill/index.js note "<url>" --visual --visual-record --pretty
# → ls ~/.js-eyes/skill-data/.../visual/<runId>/frames/
# 4) doctor 看 4 profile bridge 都注入了 __jse_visual
node skills/js-xiaohongshu-ops-skill/index.js doctor --pretty
# 5) 顶层结果字段
node skills/js-xiaohongshu-ops-skill/index.js note "<url>" --visual --json | python -c "import json,sys; r=json.load(sys.stdin); print('visual.events=', len(r['visual']['events']))"
bridges/_visual-xhs.js 通过 window.__jse_visual.setSiteAnchorResolver(fn) 把 hint.anchor 映射到具体 DOM:
| anchor | 当前页 | 优先 selector | fallback |
|---|---|---|---|
{ noteId } | 笔记详情页(URL 含同名 noteId) | #noteContainer / .note-container | .feeds-page |
{ noteId } | 搜索 / explore 列表 | a[href*='/explore/<noteId>'].closest('section.note-item') | 直接 <a> |
{ userId } | 用户主页(URL 含 /user/profile/<userId>) | .user-info-card / .user-info-wrapper / .user-page | — |
{ userId } | 列表页 | a[href*='/user/profile/<userId>'].closest('.author-wrapper') | 直接 <a> |
{ commentId } | 笔记详情页 | .comments-container / .comments-el(整片,commentId 不暴露在 DOM) | — |
resolver 命中时会多 emit 2 条 flash(pending) / flash(success) 事件(默认 hud-only 时只有 hud + before/after,共 4 条;resolver 命中后 6 条 + frame=7)。
<visualDir> 即 @js-eyes/visual-replay-hyperframes 的 jse-replay 输入;anchorId 命名空间统一为 note:<noteId> / user:<userId> / comment:<commentId>,与 lib/visualHint.js 的 extractPayload 卡片字段对齐,离线 composition 时 .flash-active 能正确附到节点。
接入统一 skill recording 底座(@js-eyes/skill-recording):
js-eyes 全局配置中的 recording.mode。--recording-mode off|history|standard|debug--debug-recording--no-cache--recording-base-dir /absolute/path--run-id custom-idv3.x:
a1/web_session/webId等敏感 cookie 在写入 history / debug 落盘前强制 mask(lib/xhsUtils.js::sanitizeForRecording)。
skills/js-xiaohongshu-ops-skill/
SKILL.md
package.json
index.js 委托 cli/index.js
skill.contract.js 工厂化 + AI 工具表
cli/index.js dispatcher(读 lib/commands.js)
lib/
api.js 编程 API(默认 useBridge)
session.js 主调度器(PAGE_PROFILES + bridge 注入)
runTool.js READ 主管道(readMode + audit + history)
config.js PAGE_PROFILES(note/search/user/home)
commands.js CLI 声明式映射
toolTargets.js 工具参数 → URL
runtimeConfig.js server/recording 配置
bridgeAdapter.js noteViaBridge / commentsViaBridge / 等
js-eyes-client.js BrowserAutomation
xhsUtils.js URL 规整 / 字段标准化 / sanitize
bridges/
common.js fetchXhsApi + parseNoteMeta + DOM helpers + detectAntiCrawl
note-bridge.js VERSION='0.1.0' getNote/getComments + 五件套
scripts/
xhs-note.js fallback(JS_XHS_DISABLE_BRIDGE=1 时使用)
tests/ node --test
auto = DOM 优先;X auto = GraphQL 优先。