A CLI for Xiaohongshu (小红书) — search, read notes, view profiles
Project description
xhs-cli 🍰
English | 中文
A command-line tool for Xiaohongshu (小红书) — search notes, view profiles, like, favorite, and comment, all from your terminal.
✨ Features
- 🔍 Search — search notes by keyword with rich table output
- 📖 Read — view note content, stats, and comments
- 👤 User Profile — view user info and stats
- 📝 User Posts — list all notes published by a user
- 🏠 Feed — get recommended content from explore page
- 🏷️ Topics — search for topics and hashtags
- ❤️ Like / Unlike — like or unlike notes
- ⭐ Favorite / Unfavorite — collect or uncollect notes
- 💬 Comment — post comments on notes
- 🔐 Auth — auto-extract cookies from Chrome, or login via QR code
- 📊 JSON output —
--jsonflag for all data commands - 🔗 Auto token —
xsec_tokenfrom search/feed results is cached and auto-resolved
📋 What Can I Do?
| Category | Commands | Description |
|---|---|---|
| 🔐 Auth | login, logout, status, whoami |
Login, logout, check status, view profile |
| 🔍 Read | search, read, feed, topics |
Search notes, read details, explore feed, find topics |
| 👤 Users | user, user-posts, followers, following |
View profile, list posts/followers/following |
| ❤️ Engage | like, unlike, comment |
Like, unlike, comment on notes |
| ⭐ Favorites | favorite, unfavorite, favorites |
Favorite, unfavorite, list all favorites |
| 📝 Post | post |
Publish a new image note |
All data commands support
--jsonfor raw JSON output.xsec_tokenis auto-cached and auto-resolved.
🏗️ Architecture
CLI (click) → XhsClient (camoufox browser)
↓ navigate to real pages
window.__INITIAL_STATE__ → extract structured data
Uses camoufox (anti-fingerprint Firefox) to browse Xiaohongshu like a real user. Data is extracted from the page's window.__INITIAL_STATE__ — completely indistinguishable from normal browsing.
📦 Installation
Requires Python 3.8+ and uv.
# Clone and install
git clone git@github.com:jackwener/xhs-cli.git
cd xhs-cli
uv sync
# Install camoufox browser
uv run python -m camoufox fetch
🚀 Usage
Login
# Auto-extract cookies from Chrome (recommended)
uv run xhs login
# Or provide cookie string manually
uv run xhs login --cookie "a1=xxx; web_session=yyy"
# Quick login check (no browser needed)
uv run xhs status
# Show full profile info
uv run xhs whoami
# Logout
uv run xhs logout
Search
# Search with rich table output
uv run xhs search "咖啡"
# JSON output
uv run xhs search "咖啡" --json
Read Note
# View note (xsec_token auto-resolved from search cache)
uv run xhs read <note_id>
# Include comments
uv run xhs read <note_id> --comments
# Provide xsec_token manually if needed
uv run xhs read <note_id> --xsec-token <token>
# JSON output
uv run xhs read <note_id> --json
User Profile & Posts
# View user profile (use internal user_id, not Red ID)
uv run xhs user <user_id>
uv run xhs user <user_id> --json
# List user's published notes
uv run xhs user-posts <user_id>
uv run xhs user-posts <user_id> --json
Feed & Topics
# Get recommended explore feed
uv run xhs feed
uv run xhs feed --json
# Search topics/hashtags
uv run xhs topics "咖啡"
uv run xhs topics "咖啡" --json
Interactions
# Like / Unlike (xsec_token auto-resolved)
uv run xhs like <note_id>
uv run xhs like <note_id> --undo
# Favorite / Unfavorite
uv run xhs favorite <note_id>
uv run xhs favorite <note_id> --undo
# Comment
uv run xhs comment <note_id> "好棒!"
Options
# Enable debug logging
uv run xhs -v search "咖啡"
# Show help
uv run xhs --help
uv run xhs search --help
📁 Project Structure
xhs-cli/
├── pyproject.toml # Project metadata and dependencies
├── uv.lock # Lock file
├── README.md
├── LICENSE
└── xhs_cli/
├── __init__.py # Package version
├── cli.py # Click CLI commands
├── client.py # Camoufox browser client
├── auth.py # Cookie extraction + QR login + token cache
└── exceptions.py # Custom exceptions
🔧 How It Works
-
Authentication: Cookies are extracted from your local Chrome browser via browser-cookie3. Falls back to QR code login if extraction fails.
-
Browsing: Each operation navigates to the real Xiaohongshu page using camoufox (a fingerprint-resistant Firefox fork). This makes all traffic look like normal user browsing.
-
Data Extraction: Structured data is pulled from
window.__INITIAL_STATE__, which is the same data React/Vue uses to render the page. -
Token Caching: After search/feed/user-posts,
xsec_tokenis automatically cached to~/.xhs-cli/token_cache.json. Subsequent commands auto-resolve tokens — no manual copy-paste needed. -
Interactions: Like, favorite, and comment work by finding and clicking the actual DOM buttons — exactly as a real user would.
⚠️ Notes
- Cookies are stored in
~/.xhs-cli/cookies.jsonwith0600permissions. - Token cache is stored in
~/.xhs-cli/token_cache.json. - The tool uses headless Firefox via camoufox — no browser window is shown.
- First run may be slower as camoufox downloads its browser binary.
- User profile lookup requires the internal user_id (hex format), not the Red ID (numeric).
📄 License
Apache License 2.0
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file xhs_cli-0.1.0.tar.gz.
File metadata
- Download URL: xhs_cli-0.1.0.tar.gz
- Upload date:
- Size: 315.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bb8653fc51cfc3b771bbe54dcbeee339db2b7497858db0067430cdb66e53d912
|
|
| MD5 |
c6e76c1cbb1de3e95244966fd5128b4f
|
|
| BLAKE2b-256 |
ad5cde559356dae9031578339e12b0af9da4973e60cbc1d071b7020f7bdc97a0
|
Provenance
The following attestation bundles were made for xhs_cli-0.1.0.tar.gz:
Publisher:
publish.yml on jackwener/xhs-cli
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
xhs_cli-0.1.0.tar.gz -
Subject digest:
bb8653fc51cfc3b771bbe54dcbeee339db2b7497858db0067430cdb66e53d912 - Sigstore transparency entry: 1039457011
- Sigstore integration time:
-
Permalink:
jackwener/xhs-cli@78cd7e3b46610eb84ad1797b5560bab1835ca2c0 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/jackwener
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@78cd7e3b46610eb84ad1797b5560bab1835ca2c0 -
Trigger Event:
push
-
Statement type:
File details
Details for the file xhs_cli-0.1.0-py3-none-any.whl.
File metadata
- Download URL: xhs_cli-0.1.0-py3-none-any.whl
- Upload date:
- Size: 27.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c3263853a8b70fea90abbfe01e43049f3ddad0d2560fcb88ef3f7b4c867c402e
|
|
| MD5 |
1bce9d2be9ad8534e15d312e77df9261
|
|
| BLAKE2b-256 |
e17ca66dc664c43672b3afbfd3c74bd2894880e5eefab399f033282c1c280dc6
|
Provenance
The following attestation bundles were made for xhs_cli-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on jackwener/xhs-cli
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
xhs_cli-0.1.0-py3-none-any.whl -
Subject digest:
c3263853a8b70fea90abbfe01e43049f3ddad0d2560fcb88ef3f7b4c867c402e - Sigstore transparency entry: 1039457054
- Sigstore integration time:
-
Permalink:
jackwener/xhs-cli@78cd7e3b46610eb84ad1797b5560bab1835ca2c0 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/jackwener
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@78cd7e3b46610eb84ad1797b5560bab1835ca2c0 -
Trigger Event:
push
-
Statement type: