Back to skills
extension
Category: OtherNo API key required

xhs 多用户

Automate Xiaohongshu (小红书/RedNote) operations via Playwright CLI — search notes, publish image/video posts, interact (like/collect/comment/follow), scrape da...

personAuthor: lv-saharanhubclawhub

---name: xhs-ts description: | Automate Xiaohongshu (小红书/RedNote) operations via Playwright CLI — search notes, publish image/video posts, interact (like/collect/comment/follow), scrape data, manage multiple accounts with isolated cookies and anti-detection. Use when user mentions 小红书, xhs, Xiaohongshu, RedNote, 红书, 小红书运营, or works with xhs-ts/ directory, or wants to login, search, publish, interact, scrape, or manage multiple Xiaohongshu accounts. license: MIT compatibility: opencode metadata: version: "0.1.1" homepage: "https://github.com/lv-saharan/skills/tree/main/xhs-ts" openclaw: emoji: "📕" requires: bins: [node, npx] install: - id: node kind: node packages: [playwright, tsx, commander, dotenv] label: "Install dependencies (playwright, tsx, commander, dotenv)"

Xiaohongshu Automation Skill (xhs-ts)

Quick Reference

| Task | Command | Status | |------|---------|--------| | Login | npm run login [-- --user <name>] | ✅ Implemented | | Search | npm run search -- "<keyword>" [-- --user <name>] | ✅ Implemented | | Publish | npm run publish -- [options] [-- --user <name>] | ✅ Implemented | | User Management | npm run user | ✅ Implemented | | Like | npm run like -- "<url>" [urls...] [-- --user <name>] | ✅ Implemented | | Collect | npm run collect -- "<url>" [urls...] [-- --user <name>] | ✅ Implemented | | Comment | npm run comment -- "<url>" "text" | ✅ Implemented | | Follow | npm run follow -- "<url>" [urls...] | ✅ Implemented | | Scrape note | npm run scrape-note -- "<url>" | ✅ Implemented | | Scrape user | npm run scrape-user -- "<url>" | ✅ Implemented | | Browser start | npm run browser -- --start [--user <name>] | ✅ Implemented | | Browser status | npm run browser -- --status | ✅ Implemented | | Browser stop | npm run browser -- --stop | ✅ Implemented |

All commands support --user <name> for multi-account operations.

Usage: npm run <command> -- [args] -- [options]

Example: npm run search -- "美食" -- --limit 10 --user "小号"


Gotchas

Authentication

  1. Cookie expiry — Session cookies expire after ~30 days; NOT_LOGGED_IN → run npm run login
  2. Comment requires phone binding — Unbound accounts get 评论受限: 绑定手机
  3. URL must include xsec_token — Direct URLs may not work; use npm run search to get complete URLs

Anti-Detection

  1. Rate limiting — Keep 2-5 second intervals between operations
  2. Headless auto-detection — Linux servers (no DISPLAY) automatically force headless mode
  3. QR code file path — Headless mode: QR saved to users/{user}/tmp/qr_login_*.png

Platform Limits

  1. Short links not supported — xhslink.com URLs will fail; use full URLs
  2. Publish detection risk — Xiaohongshu may block automated publishing; test with secondary account

Multi-User Management

xhs-ts supports multiple Xiaohongshu accounts with isolated cookies and temporary files.

Directory Structure

xhs-ts/
├── users/                    # Multi-user directory
│   ├── users.json            # User metadata (current user, version: 3)
│   ├── default/              # Default user
│   │   ├── user-data/        # Playwright persistent context (auto-saves cookies, localStorage)
│   │   ├── profile.json      # Unified Profile data (meta + connection)
│   │   ├── fingerprint.json  # Device fingerprint
│   │   └── tmp/              # Temporary files (QR codes)
│   └── {username}/           # Same structure as default/
│       ├── user-data/
│       ├── profile.json
│       ├── fingerprint.json
│       └── tmp/

Version 3 Changes: meta.json merged into profile.json with meta and connection fields.

User Selection Priority

--user <name>  >  users.json current  >  default

Commands

# List all users
npm run user

# Set current user
npm run user:use -- "小号"
# Or: npm run user -- --set-current "小号"

# Reset to default user
npm run user -- --set-default

# Clean up corrupted user data (when login fails with USER_DATA_CORRUPTED)
npm run user -- --cleanup '<用户名>'

# Login with specific user
npm run login -- --user "小号"

# Search with specific user
npm run search -- "美食" --user "小号"

Error Recovery: Corrupted User Data

When login fails with USER_DATA_CORRUPTED error, the output includes suggestCleanup: true:

{
  "error": true,
  "code": "USER_DATA_CORRUPTED",
  "suggestCleanup": true,
  "canCleanup": true,
  "hint": "用户数据可能已损坏。请运行 npm run user -- --cleanup <用户名> 清理后重新登录。"
}

Agent workflow:

  1. Detect suggestCleanup: true in error output
  2. Ask user: "用户数据可能已损坏,是否执行清理?"
  3. If user confirms: run npm run user -- --cleanup <用户名>
  4. After cleanup succeeds: run npm run login -- --user <用户名>

Safety check: Cleanup is blocked (canCleanup: false) if browser is running for that user. Close browser first with npm run browser -- --stop-user <用户名>.


Output Format

All commands output JSON to stdout. The toAgent field provides actionable instructions.

toAgent Format

ACTION[:TARGET][:HINT]

| Action | Agent Behavior | |--------|---------------| | DISPLAY_IMAGE | Use look_at to read image, send based on Channel type | | RELAY | Forward message directly to user | | WAIT | Wait for user action, prompt HINT text | | PARSE | Format data content and display |

Channel-Specific Formatting

When toAgent is PARSE:notes, format output based on channel type:

| Channel | Format | Key Rule | |---------|--------|----------| | 飞书 | 交互卡片 + 反引号URL(逐条循环) | 每条 2 条消息;间隔 600ms+ | | 微信个人号 | 文字 + 图片(逐条发送) | 文字在前;每次一条,等待返回 | | 企业微信 | 图文 news 或 Markdown | picurl 直接用 | | CLI | 表格 | 标准输出 |

完整格式规范、JSON 模板、回调处理见 references/channel-integration.md


Commands

Login

# QR code login (default)
npm run login

# Headless mode (QR saved to file)
npm run login -- --headless

# SMS login
npm run login -- --sms

# SMS login with phone number
npm run login -- --sms --phone "13800138000"

# Cookie string login (direct import)
npm run login -- --cookie-string "a1=xxx; webId=xxx; ..."

# Login with specific user
npm run login -- --user "小号"

| Parameter | Values | Default | |-----------|--------|---------| | --qr | QR code login | ✅ Default | | --sms | SMS login | — | | --phone | Phone number for SMS | — | | --cookie-string | Cookie string for direct login | — | | --headless | Run in headless mode | false | | --timeout | Login timeout (ms) | 120000 | | --user | User name | current user |

Search

# Basic search
npm run search -- "美食探店"

# With filters
npm run search -- "美食探店" --limit 10 --sort hot --note-type image --time-range week

# Search followed users only
npm run search -- "美食探店" --scope following

Output formatting: For sending results to Feishu/WeChat, see references/channel-integration.md

| Parameter | Values | Default | |-----------|--------|---------| | --limit | Any positive integer | 10 | | --skip | Non-negative integer | 0 | | --sort | general, time_descending, hot | general | | --note-type | all, image, video | all | | --time-range | all, day, week, month | all | | --scope | all, following | all | | --location | all, nearby, city | all |

Publish

# Publish image note
npm run publish -- --title "标题" --content "正文" --images "img1.jpg,img2.jpg"

# Publish video note
npm run publish -- --title "标题" --content "正文" --video "video.mp4"

# With tags
npm run publish -- --title "标题" --content "正文" --images "img1.jpg" --tags "美食,探店"

⚠️ Warning: Xiaohongshu may detect and block automated publishing. Use secondary account for testing.

Interact (Like, Collect, Comment, Follow)

All interact commands require:

  • Login: Must be logged in
  • Valid URL: URLs must include xsec_token parameter

Use npm run search to get complete URLs with tokens.

Like

# Single note
npm run like -- "https://www.xiaohongshu.com/explore/noteId?xsec_token=xxx"

# Multiple notes (batch)
npm run like -- "url1" "url2" "url3"

# Custom delay between likes (default: 2000ms)
npm run like -- "url1" "url2" --delay 3000

Collect (Bookmark)

# Single note
npm run collect -- "https://www.xiaohongshu.com/explore/noteId?xsec_token=xxx"

# Multiple notes (batch)
npm run collect -- "url1" "url2"

# Custom delay between collects (default: 2000ms)
npm run collect -- "url1" "url2" --delay 3000

Comment

# Comment on a note
npm run comment -- "https://www.xiaohongshu.com/explore/noteId?xsec_token=xxx" "评论内容"

# With specific user
npm run comment -- "url" "评论内容" --user "小号"

⚠️ Phone Binding Required: Accounts without phone number cannot comment. Error: 评论受限: 绑定手机

Follow

# Follow single user
npm run follow -- "https://www.xiaohongshu.com/user/profile/userId"

# Follow multiple users (batch)
npm run follow -- "url1" "url2"

# Custom delay between follows (default: 2000ms)
npm run follow -- "url1" "url2" --delay 3000

Scrape

Scrape Note

# Basic scrape
npm run scrape-note -- "https://www.xiaohongshu.com/explore/noteId?xsec_token=xxx"

# Include comments
npm run scrape-note -- "url" --comments --max-comments 50

| Parameter | Values | Default | |-----------|--------|---------| | --comments | Include comments in output | false | | --max-comments | Max comments to fetch | 20 |

Output: noteId, title, content, images, video, author, stats, tags, publishTime, location

Scrape User

# Basic scrape
npm run scrape-user -- "https://www.xiaohongshu.com/user/profile/userId"

# Include recent notes
npm run scrape-user -- "url" --notes --max-notes 24

| Parameter | Values | Default | |-----------|--------|---------| | --notes | Include recent notes in output | false | | --max-notes | Max notes to fetch | 12 |

Output: userId, name, avatar, bio, stats, tags, recentNotes

Browser Management

Browser instances run in detached mode and persist after CLI exits. Agent is responsible for closing idle browsers.

# Start browser instance
npm run browser -- --start
npm run browser -- --start --user "小号"
npm run browser -- --start --headless

# Show status (includes lastActivityAt timestamp)
npm run browser -- --status

# List saved connections
npm run browser -- --list

# Stop instances
npm run browser -- --stop-user "小号"  # Stop specific user
npm run browser -- --stop              # Stop all instances

| Parameter | Description | |-----------|-------------| | --start | Start a browser instance | | --stop | Stop all browser instances | | --stop-user <name> | Stop browser for specific user | | --status | Show browser status (includes lastActivityAt) | | --list | List saved CDP connections | | --user <name> | User name (for --start) | | --headless | Run in headless mode |

Agent Responsibility: Check lastActivityAt from --status output. Close idle browsers (e.g., inactive for 20+ minutes) to free resources.


Agent Workflow

Typical User Requests

| User says | Agent should | |-----------|-------------| | "搜索 XX" | npm run search -- "XX" → 根据 Channel 格式化输出 | | "帮我点赞这个笔记" | 验证 URL 含 xsec_tokennpm run like -- "<url>" | | "发布一篇笔记" | npm run publish -- --title ... --content ... --images ... | | "抓取这个笔记的数据" | npm run scrape-note -- "<url>" | | "切换账号" | npm run user:use -- "<name>"npm run login -- --user "<name>" |

Error Handling Flow

  1. 命令返回 NOT_LOGGED_INnpm run login
  2. 命令返回 USER_DATA_CORRUPTED → 询问用户 → npm run user -- --cleanup
  3. 命令返回 RATE_LIMITED → 等待 30s → 重试
  4. 浏览器空闲 20+ 分钟 → npm run browser -- --stop

Full error code reference: references/troubleshooting.md


References