This skill is xhs-* A merged version of, the goal is to let users only need clawhub install xhs-skill once to start using it.
Constraints:
- All browser interactions (open page/click/input/upload/screenshot/login/export) are entirely delegated to
agent-browser-stealth。 - Writing/maintaining publishing orchestration scripts in this repository is prohibited (e.g.,
publish_from_payload); the publishing action must be performed in the session byagent-browser-stealth. - Use of
agent-browseris prohibited (the old channel is disabled, uniformly useagent-browser-stealth)。 - All sensitive data (cookies, export files, screenshots) is only stored locally in the
data/directory; do not paste it into chat.
Hard execution constraints (stability):
- The same
agent-browser-stealthsession must not perform concurrent operations (execute serially), otherwise it is easy to triggeros error 35false failures. snapshot's refs will drift: before and after key actions,snapshot -imust be re-captured, andplaceholder/role/textshould be used as a secondary positioning fallback.- Scanning the QR code does not mean login succeeded; post-validation must be performed (see Section A below, "Login Success Determination").
Installation
clawhub install xhs-skill
cd skills/xhs-skill
npm i
Note:npm i is only used for the local CLI bundled with this skill (QR code decoding, cookies tool). If you do not need to decode QR codes/convert cookies, you can also just use agent-browser-stealth to complete QR scanning and export.
Directory conventions (local machine)
It is recommended to prepare the following in the working directory where you run commands:
data/xhs_login_qr.png: login page QR code screenshot (PNG)data/raw_cookies.json: exported raw cookies (JSON)data/xhs_cookies.json: normalized cookies (JSON)data/exports/<YYYY-MM-DD>/: exported data (CSV/XLSX/screenshots)data/assets/<YYYY-MM-DD>/: icons/illustration assets and source records used for publishing notes
mkdir -p data
A. Log in (QR scan) and save cookies
Goal: log in to the Xiaohongshu Creator Center and export cookies to avoid frequent repeated logins.
- Use
agent-browser-stealthto open the login page:
https://creator.xiaohongshu.com/login- If "Phone number/verification code login" is displayed by default, click "QR scan" to switch to the QR code view
-
Have
agent-browser-stealthtake a screenshot and save the QR code (PNG) todata/xhs_login_qr.png -
(Optional) Use the local CLI to decode the QR code text and print an ASCII QR code:
node ./bin/xhs-skill.mjs qr show --in ./data/xhs_login_qr.png
OpenClaw return specification (mandatory):
- It is prohibited to return only a file path (for example, only saying
data/xhs_login_qr.png)。 - You must first execute
node ./bin/xhs-skill.mjs qr show --in ./data/xhs_login_qr.png, then send the output QR code text + ASCII QR code directly to the user. - If the session supports image rendering, then also attach the absolute path of the QR code screenshot (or an image attachment) as a supplement.
- After sending the QR code, you must pause and wait for the user to confirm "scanned" before continuing with cookies export.
Recommended return template:
请用小红书 App 扫这个二维码登录。
二维码文本: <qr_text>
<ASCII QR>
- After completing login by scanning the QR code with the Xiaohongshu App, export cookies to
data/raw_cookies.json(without going through DevTools):
agent-browser-stealth cookies --json > ./data/raw_cookies.json
- Normalize cookies and save them to
data/xhs_cookies.json:
node ./bin/xhs-skill.mjs cookies normalize --in ./data/raw_cookies.json --out ./data/xhs_cookies.json
node ./bin/xhs-skill.mjs cookies status --in ./data/xhs_cookies.json
5.1 It is recommended to use a script for post-validation (executable gate):
# 例:先让 agent-browser-stealth 记录当前 URL 与后台探测后的 URL
CURRENT_URL="$(agent-browser-stealth get url)"
agent-browser-stealth open https://creator.xiaohongshu.com/creator/home
PROBE_FINAL_URL="$(agent-browser-stealth get url)"
node ./scripts/verify_login.mjs \
--cookies ./data/xhs_cookies.json \
--current-url "$CURRENT_URL" \
--probe-final-url "$PROBE_FINAL_URL" \
--json
Login success determination (mandatory):
- Both of the following 2 conditions must be met before reporting "login complete" (
web_sessionis no longer a hard dependency): - The current URL has left
/login - Able to access the creator backend page without 401/redirecting back to login
- Bonus: a "session-like cookie" exists in cookies (for example
web_session, or the cookie name containssession). It may still work without it, but stability is worse. - If any mandatory condition is not met, you must report "login failed/incomplete" and retry the login process; false success reporting is prohibited.
Login result output contract (JSON):
{
"task": "xhs_login",
"ok": true,
"checks": {
"left_login": true,
"backend_not_rejected": true,
"has_session_like_cookie": true
},
"artifacts": {
"qr_png": "data/xhs_login_qr.png",
"raw_cookies": "data/raw_cookies.json",
"normalized_cookies": "data/xhs_cookies.json"
}
}
On failure ok=false, and provide the failed item (for example still on /login, or probe redirecting back), outputting "completed" is prohibited.
- (Optional) generate
Cookie:header:
node ./bin/xhs-skill.mjs cookies to-header --in ./data/xhs_cookies.json
Failure fallback:
- QR code decoding failure: usually because it did not switch to the scan view or the QR code is too small; have
agent-browser-stealthenlarge it and take a new screenshot (still PNG). - Cookies normalization failure: keep the original
data/raw_cookies.json, and expand compatibility branches later.
A1. Anti-ban/rate-limit operating rules (mandatory)
Core conclusion: Xiaohongshu risk control mainly looks at "rhythm + fingerprint + behavior + IP + account weight". The tool itself is not the main cause; how it is used is the main cause.
Mandatory strategy:
- Human-like rhythm:
- Continuous clicking/filling without pauses is prohibited; random pauses must be inserted between key actions (recommended
1.2s~7s)。 - For input, prefer
type --delay(character by character), avoiding full instantaneousfill。
- Fixed fingerprint:
- When running the publishing process, prioritize fixing
--profile, and enable--headed。 - It is recommended that the same account reuse the same profile directory over the long term; do not create a new temporary environment every time.
- Publishing frequency gate:
- For the same profile, by default
24h <= 3posts. - The default minimum interval between two publishes is
30minutes. - If the gate is hit, it must be stopped; forced publishing is not allowed.
- Pre-publish warm-up behavior:
- First do a short period of normal browsing (stay on the homepage/creator backend + scroll), then enter the publishing page.
- "Submitting immediately after opening the page" is prohibited.
- Network and device:
- Data center IPs / high-frequency proxy switching are prohibited.
- Prefer home network or mobile hotspot; for the same account, try to keep the device/IP stable.
- Handling after being rate-limited:
- Rate limiting: stop automation and return to normal manual use for
3~7days. - Account ban: only appeal is possible; when changing accounts, also change
profile + IP + 设备环境。
B. Publish note (image-text/video)
Input (provided by user):
- Note type: image-text or video
- Title, body, tags (required)
- Topic (required; when doing hot-topic publishing it must be "today's hot topic")
- Image/video path (local absolute path preferred)
- Icon/accompanying image requirements (optional): keywords, style (flat/skeuomorphic/linear), primary color, whether transparent background
- Hot-topic source (required): source name, source URL, source date (
YYYY-MM-DD)
Publishing hard gate (mandatory):
- First organize the publishing materials as
data/publish_payload.json(example):
{
"topic": "今日热点:xxxx",
"source": {
"name": "央视新闻",
"url": "https://example.com/news",
"date": "2026-02-12",
"evidence_snippet": "2月12日该媒体报道提到:......",
"key_facts": ["关键事实1(含日期/数字)", "关键事实2(含日期/数字)"]
},
"post": {
"title": "20字内标题示例",
"body": "不少于 80 字的正文......",
"tags": ["#热点", "#今日新闻", "#小红书运营"],
"real_topics": ["#人工智能", "#AI资讯", "#科技观察"],
"media": ["/abs/path/cover.png", "/abs/path/card_1.png"]
}
}
- The validation script must be executed before publishing:
# 普通模式
node ./scripts/verify_publish_payload.mjs --in ./data/publish_payload.json --policy ./config/verify_publish_policy.json --tag-registry ./data/tag_registry.json --min-registry-tags 12 --require-source-evidence on --strict-anti-ai on --json
# 今天热点模式(强制 source.date = 今天)
node ./scripts/verify_publish_payload.mjs --in ./data/publish_payload.json --policy ./config/verify_publish_policy.json --tag-registry ./data/tag_registry.json --min-registry-tags 12 --require-source-evidence on --strict-anti-ai on --mode hot --json
- The content review script must be executed before publishing (layered rules + AI):
node ./scripts/review_publish_payload.mjs --in ./data/publish_payload.json --policy ./config/review_policy.json --taxonomy ./config/review_taxonomy.json --ai-provider auto --require-ai off --mode hot --json
- Only when the validation and review results are both
ok=trueOnly then is one allowed to enter the publish page and click "Publish/Submit". The validation policy is in./config/verify_publish_policy.json, the review policy is in./config/review_policy.json, and the layered risk paths are in./config/review_taxonomy.json。 - If any gate fails, the process must be aborted and a prompt to complete the missing items must be shown; "just uploading a screenshot and publishing directly" is prohibited.
Prohibited links (mandatory):
- No links or domain-like forms may appear in the title/body/tags (
http/https、www.、xxx.com/.cn/...). Otherwise there is a risk of being banned. - If content generation encounters difficulties or fails validation: it is better to abort than to "just post something random".
Anti-AI-detection and authentic tags (mandatory):
- Do not promise "100% undetectable as AI"; the goal is to significantly reduce risk.
- The body must contain a "personal perspective + specific factual signals (numbers/dates/source mentions)" and avoid template-speak.
- Before publishing, it must pass the
review_publish_payloadreview gate, requiringdecision=pass, and outputrisk_path, evidence, andreview_queuefor re-review. source.evidence_snippetandsource.key_factsare required, and must be traceable to source facts.- Tags and
post.real_topicsmust both come from the real topic pooldata/tag_registry.json, and creating tags yourself is prohibited. - Automatically concatenating
#标签into the body to impersonate a topic is prohibited. - Before publishing, at least 3 real topics must be manually selected on the Xiaohongshu publish page, and then
agent-browser-stealthexecutes the final publish click.
Example: prepare a real tag pool (recommended to update daily):
cat > ./data/tag_registry.json <<'JSON'
{
"updated_at": "2026-02-24",
"source": {
"platform": "xiaohongshu",
"method": "manual_from_publish_topic_picker",
"url": "https://creator.xiaohongshu.com/creator/publish"
},
"tags": ["#AI热点", "#人工智能", "#行业观察", "#科技新闻", "#AI资讯", "#科技观察"]
}
JSON
Publishing execution method (the only one):
- This repository is only responsible for "data preparation + gate validation + review validation"; it no longer provides publishing automation scripts.
- Browser actions must be executed serially by
agent-browser-stealth: pre-check -> fill -> read-back validation -> publish -> post-check. - If any gate fails (
verify/reviewis notok=true), it must stop at "before publishing", and continuing to click submit is prohibited.
P0: Publishing orchestrator (process orchestration, not a repository script):
- Pre-check:
- The entry route is fixed to enter from
https://creator.xiaohongshu.com/publish/publish; using/creator/*as the first entry point is prohibited. - If redirected to
https://creator.xiaohongshu.com/new/home("the page you visited is gone"), immediately return to/publish/publishand retry. - After entering the publish page, first switch to "Image and Text" mode, then upload images; do not proceed to subsequent steps without switching to Image and Text.
- Fill:
- Write the title, body, tags/topics, and visibility.
- Read-back validation:
- Only after validation passes is clicking publish allowed.
- Publish:
- After clicking publish, wait for the page state to stabilize and record the URL.
- Post-check:
- First check that the URL parameters include
published=true; - , then enter "Note Management" from the page menu for a second confirmation; hardcoding a direct link to the management page for post-checking is not allowed.
P0: Routing and state stability (mandatory):
- Only
/publish/publishis recognized as the stable entry point; other pages serve only as transit and are not used as the basis for determining success. - "The publish page is available" does not equal "the management page is available": after publishing, a second check via menu navigation is mandatory.
- If the publish page elements do not appear, first check whether it is in the "Image and Text mode + images uploaded" state, and only then determine failure.
P0: Selector dual-channel (mandatory):
- First channel (default): semantic targeting (
placeholder + role + 可见性 + 附近文案)。 - Second channel (fallback): DOM structure cue targeting (e.g., title input placeholder semantics + body editor
tiptap/ProseMirrorsemantic class names). - Do not rely solely on
snapshot refor@e1/@e2indices; before and after every key action, performsnapshot -isecondary confirmation. - DOM fallback is only used as a session-level temporary measure; after a hit, a "read-back verification" is still required to confirm the field is correct, and fragile selectors must not be treated as hard dependencies.
P0: Write reliability (mandatory):
- The title field must satisfy: single-line, visible, editable, placeholder matches "title" semantics.
- The body field must satisfy: multi-line or
contenteditable, visible, editable, placeholder/nearby text matches "body/content" semantics. - After writing, a "bidirectional read-back verification" must be performed: read both title and body simultaneously, compute
title_lenandbody_len。 - Misplacement determination: if
title_len > 20andbody_len < 80, or the title matches long-form body characteristics (large number of line breaks/periods), it is determined to be a write misplacement. - Misplacement self-healing: automatically perform "swap rewrite" once (clear title and body -> write short title to title -> write body to body -> read back and re-verify); if it still fails, abort and report failure; do not continue to submit.
- Mandatory rule: the title must not contain
#tags, long-form body, links; tags must be selected through the Xiaohongshu publish page's "tag/topic interaction", and tag text must not be stuffed into the title.
P0: Draft confirmation closed loop (mandatory):
- After clicking "Save and Leave", you must wait for and verify a "saved successfully/draft saved" type toast.
- Enter the draft list and verify that a "new draft entry" appears.
- New entry verification must include at least:
- The title prefix matches this title;
- The timestamp is within this run window (2 minutes recommended);
- After opening the draft, read back
title/body/media/tagsstill satisfies the gate.
- If any verification fails, it is determined to be "draft save failure"; retry is allowed once; if it still fails after retry, abort the process.
P0: Image preprocessing (no-script version):
- Do not add repository scripts; uniformly adopt "local preprocessing before publishing + read-back size confirmation".
- Recommended target size:
1242x1660(3:4 portrait). - Optional command (single execution, not committed to repository scripts):
# macOS: 先居中裁剪再缩放到 1242x1660(按需替换输入输出路径)
sips -c 1660 1242 ./data/assets/in.png --out ./data/assets/out_1242x1660.png
- After uploading, you must confirm on the publish page that the thumbnail ratio is normal; if stretching/cropping is abnormal, replace the asset first before continuing.
P0: Hard pre-publish verification (mandatory):
- Title length
<= 20。 - Body length
>= 80。 - Image uploaded (at least 1 for image-text, and thumbnail visible).
- A real topic has been selected
>= 3(selected through Xiaohongshu topic interaction, not concatenated in the body). - Title/body/tags contain no link words (
http、https、www., domain forms). - If any is not satisfied, abort directly; "publish first then fix" is not allowed.
P0: Dual confirmation after publishing (mandatory):
- First: after publishing, the URL contains
published=true。 - Second check: enter "Note Management" from the publish page menu, and confirm that the new note appears in the list (title prefix + time window).
- If the management page is redirected or unreachable, determine that the "recheck is incomplete" and record
run_logand prompt for manual review.
P1: Hot topic to payload semi-automatic (script-free version):
- Do not add a new
newsnow -> payloadcode generator; instead use session template filling. - After collecting hot topics, generate
data/publish_payload.jsonaccording to the following template, and manually modify only the "opinion paragraph":
{
"topic": "今日热点:<主题>",
"source": {
"name": "<来源名>",
"url": "<来源URL>",
"date": "YYYY-MM-DD",
"evidence_snippet": "<原文证据摘录>",
"key_facts": ["<事实1:含日期/数字>", "<事实2:含日期/数字>"]
},
"post": {
"title": "<8-20字标题,不含标签>",
"body": "<观点段+事实段,不少于80字>",
"tags": ["#标签1", "#标签2", "#标签3"],
"real_topics": ["#真实话题1", "#真实话题2", "#真实话题3"],
"media": ["/abs/path/1.png"]
}
}
P1: Label/topic pool maintenance (script-free version):
- Before the first publication each day, manually refresh once
data/tag_registry.json(copy from the topic selector on the Xiaohongshu publish page). - If it has not been refreshed that day, the process must report a risk warning and recommend refreshing before publishing.
- The gate remains unchanged:
tagsandreal_topicsmust both hittag_registry。
P1: Process observability (script-free version):
- At the end of each run, produce
data/run_log/<YYYY-MM-DD_HH-mm-ss>.json(manually writing the file is sufficient; do not add a new script). - Suggested fields:
steps、durations_ms、failed_step、error_message、screenshots、result_url、draft_check、editor_check、route_check、post_publish_check。
P1: Fixed template (strongly recommended):
- Fixed title template:
[主题词]+[观点/结论], target 1218 characters, leave 28 characters of buffer to avoid exceeding the limit. - Fixed body template:
开场观点 -> 事实1 -> 事实2 -> 个人判断 -> 行动建议, default >120 characters. - Fixed label and topic pool: select only from
data/tag_registry.json, to avoid gate failures caused by creating words on the spot.
P2: Regression cases (daily smoke, manually executed):
- Scenario 1: Save draft only (do not publish).
- Scenario 2: Save as draft, edit a second time, then save as draft again.
- Scenario 3: Formal publication (passes all gates).
- Each scenario outputs one
run_log, used to compare "positioning stability/misalignment rate".
Process (everything on the browser side is completed by agent-browser-stealth ):
- Ensure you are logged in (first complete A above, or already have a valid login state).
- Prepare and validate
data/publish_payload.json(mustok=true)。 - Open
https://creator.xiaohongshu.com/publish/publish, firstsnapshot -ito obtain the latest structure. - Switch to image-text mode and upload media (confirm thumbnail aspect ratio and quantity).
- Fill in the title and body using "semantic positioning first + DOM fallback"; after writing, perform "bidirectional read-back validation + misalignment self-healing".
- Select labels and real topics through Xiaohongshu label interaction (at least 3), and do not write labels into the title.
- Perform hard validation before publishing (title, body, images, topics, no link words).
- Click "Save and Leave" and perform draft closed-loop validation (toast + new list entry + read-back).
- Pause before clicking "Publish/Submit", and require the user to confirm the final preview.
- After publishing, perform double confirmation (
published=true+ enter Note Management from the menu for a second check), and writerun_log。
Publish result output contract (JSON):
{
"task": "xhs_publish",
"ok": true,
"result_url": "https://creator.xiaohongshu.com/....",
"content_checks": {
"title_len": 18,
"body_len": 136,
"tag_count": 3,
"real_topic_count": 3,
"editor_alignment_ok": true,
"draft_saved_ok": true,
"publish_precheck_ok": true,
"published_param_ok": true,
"manage_menu_check_ok": true,
"topic": "今日热点:xxxx",
"source_date": "2026-02-12"
},
"artifacts": {
"payload_json": "data/publish_payload.json",
"media_inputs": ["..."],
"run_log_json": "data/run_log/2026-02-27_14-36-00.json",
"error_screenshot": null
}
}
When publishing fails, ok=false, and return the error_message、error_screenshot path, the failed missing_checks and failed_stage(preflight/fill/readback/publish/postcheck)。
C. Export creator center data (CSV/XLSX or screenshot)
Goal: export key creator center data to data/exports/<YYYY-MM-DD>/for subsequent analysis.
- Confirm you are logged in.
- Use
agent-browser-stealthto enter the commonly used analytics pages in the Creator Center (dashboard/content analytics/follower analytics). - Each page:
- Prefer using the page's built-in export (if available) to
data/exports/<date>/ - When there is no export: save screenshots of key sections to the same directory
- Record: export time range, metric definitions, page URL.
Local CLI (included with this skill)
Commands:
node ./bin/xhs-skill.mjs qr show --in <pngPath>node ./bin/xhs-skill.mjs cookies normalize --in <jsonPath> --out <outPath>node ./bin/xhs-skill.mjs cookies status --in <cookiesJsonPath>node ./bin/xhs-skill.mjs cookies to-header --in <cookiesJsonPath>node ./scripts/verify_publish_payload.mjs --in <payloadJsonPath> --policy ./config/verify_publish_policy.json --tag-registry ./data/tag_registry.json --min-registry-tags 12 --require-source-evidence on --strict-anti-ai on [--mode hot]node ./scripts/review_publish_payload.mjs --in <payloadJsonPath> --policy ./config/review_policy.json --taxonomy ./config/review_taxonomy.json --ai-provider auto --require-ai off [--mode hot]
D. Lightweight release process (maintainers)
- First run the local gate:
npm run check:constraintsnpm test
- Check that the changes include only the expected files:
git status --short - Commit using a Chinese Conventional Commit (example):
docs(skill): 补充发版前快速自检清单
- Publish to ClawHub (patch):
clawhub sync --all --bump patch --changelog "docs: 补充发版前快速自检清单"