Skip to content
xhs

v0.2.0

Anonymous reads from the server-rendered page, plus a crawl engine and usage-first docs.

This release teaches xhs to read public data without a cookie, fixes the profile login wall, makes the exit codes honest, and grows crawl into a small scraping engine. The docs are rewritten around how to use each command.

The signed JSON API answers -101 needs login to an anonymous caller. The web client does not: it ships the data inside the server-rendered page as window.__INITIAL_STATE__. xhs now reads that page first and only falls back to the signed API when you pass a logged-in cookie.

In practice:

  • note and feed work anonymously. No cookie, no token gymnastics beyond the note's own xsec_token.
  • user, user --notes, and related work from a cold IP and get rate-walled once the IP is hot.
  • comments, search, suggest, tag, and me still need a cookie, since the site does not server-render them.

The new pkg/xhshtml package pulls __INITIAL_STATE__ out of the HTML and cleans up the undefined/NaN the page leaves in its JSON.

The profile login-wall fix

Fetching a profile with an in-site Referer header made the site treat the call as an in-app navigation and bounce it to /login. Dropping the Referer on the web reads returns the full page again. xhs also detects a redirect to /login and reports it as a surface that needs a cookie rather than a confusing network error.

Honest exit codes

A walled or login-only surface now exits 3 (needs a cookie) instead of exiting 0 with empty output or 6 with a wrapped error. Batch commands like note and user return the underlying error when nothing resolved, so a fully blocked run fails loudly. The full table:

Code Meaning
0 success
3 the surface needs a login cookie
4 not found
5 rate-limited or walled by anti-bot
6 network error
1 any other error

A crawl engine

xhs crawl walks outward from seed notes and streams connected records as JSONL, one file per kind, into an output directory:

xhs crawl <note-id> --token <t> --out ./data --comments
xhs feed --category food -o url | xhs crawl - --out ./data

It writes notes.jsonl, users.jsonl, and comments.jsonl as it goes, so a run that stops early still leaves usable data on disk. Flags pick what to follow: --user and --related are on by default, --comments (with --deep for replies) is opt-in.

Usage-first docs

The docs now lead with how to use each command instead of how it works. The new commands reference shows every command with the call and a sample of what it prints. The introduction is trimmed to which commands need a cookie.

Install

go install github.com/tamnd/xiaohongshu-cli/cmd/xhs@latest

Or download a prebuilt binary from the release, or run ghcr.io/tamnd/xhs:0.2.0.