# How to search Xiaohongshu notes and export them to CSV

> Search Xiaohongshu by keyword with sort and note-type filters, page through the results, fetch full text and every image of the notes you keep, and save one CSV.

Canonical page: https://okdata.online/guides/xiaohongshu-search-export-notes/

Two endpoints: Xiaohongshu note search, paged with its cursor, then Xiaohongshu note detail for the notes whose full text and images you need. The worked example below is 8 calls and costs $0.16; a failed call is not charged.

Updated 2026-11-12

The job: you want a spreadsheet of what Xiaohongshu shows for a keyword, the notes, who wrote them and how they did, plus the complete text and pictures of the handful that stand out. Content teams use it to brief writers, product teams to see how people describe a category, analysts to track a topic week by week. Search returns note cards; detail returns the whole note. You end with one CSV: every note from the search pages, and for the top five also the full text and every image URL.

No Xiaohongshu account, cookie or xsec_token is involved.

## Step by step

### Step 1: search, with sort and type

Call [Xiaohongshu note search](https://okdata.online/apis/xiaohongshu/notes/search/) with `query` the way a person types it: `露营`, `露营 装备清单`, `新手露营`. Two parameters change what you get:

- `sort`: `general` (the default, Xiaohongshu's own ranking), `latest` (newest first) or `popular` (most engagement first). `latest` is the one for tracking a topic over time; `popular` for "what works".
- `type`: `all` (the default), `image` for image notes or `video` for video notes.

One call returns about 20 notes for $0.02. Each card has `id`, `url`, `type`, `title`, `author` (name and ID), `published_at`, `hashtags` and `metrics`: `likes`, `favorites` (saves), `comments` and `shares`. The `text` on a search card is only the opening of the note, and `images` usually holds the cover alone.

```bash
curl -G "https://api.okdata.online/v1/xiaohongshu/notes/search" \
  -H "Authorization: Bearer $OKDATA_API_KEY" \
  --data-urlencode 'query=露营' \
  --data-urlencode 'sort=latest' \
  --data-urlencode 'type=image'
```

### Step 2: page through the results

For the next page, send `page.next_cursor` back as `cursor`, unchanged, with the same `query`, `sort` and `type`. Stop when `page.has_more` is `false`, or when you have enough: every page is one call. Results drift further from your keyword the deeper you page, so a few pages of a narrow query (`露营 装备清单`) usually tell you more than many pages of a broad one (`露营`).

### Step 3: fetch full notes for the ones you keep

[Xiaohongshu note detail](https://okdata.online/apis/xiaohongshu/notes/get/) takes `id` (or a note link or xhslink share link as `url`) and returns the full note for $0.02: the whole `text`, every image in `images`, `hashtags`, and fresh `metrics`. A video note gives its cover image, not the video file.

```bash
curl -G "https://api.okdata.online/v1/xiaohongshu/notes/get" \
  -H "Authorization: Bearer $OKDATA_API_KEY" \
  --data-urlencode 'id=672a4f1d000000001b03c58e'
```

Fetch detail only for the notes you will read. Search cards already carry the counts, so a table of 60 notes with likes and saves needs no detail calls at all.

### Step 4: the script

The script reads three pages of the latest image notes, picks the five with the most saves, fetches them in full and writes one CSV with a row per note.

```python
import csv
import os
import requests

API = "https://api.okdata.online"
HEADERS = {"Authorization": f"Bearer {os.environ['OKDATA_API_KEY']}"}
SEARCH_PAGES = 3  # each page is one call
FULL_NOTES = 5    # notes to fetch in full; each is one call


def get(path, **params):
    body = requests.get(API + path, headers=HEADERS, params=params, timeout=60).json()
    if body["code"] != "ok":
        raise RuntimeError(f"{body['code']}: {body['message']} (charged: {body['charged']})")
    return body


notes, cursor = [], None
for _ in range(SEARCH_PAGES):
    params = {"query": "露营", "sort": "latest", "type": "image", **({"cursor": cursor} if cursor else {})}
    body = get("/v1/xiaohongshu/notes/search", **params)
    notes += body["data"]["items"]
    if not body["page"]["has_more"]:
        break
    cursor = body["page"]["next_cursor"]

notes = list({n["id"]: n for n in notes}.values())  # drop repeats across pages
top = sorted(notes, key=lambda n: n["metrics"]["favorites"] or 0, reverse=True)[:FULL_NOTES]
full = {n["id"]: get("/v1/xiaohongshu/notes/get", id=n["id"])["data"]["item"] for n in top}

with open("xhs_notes.csv", "w", newline="", encoding="utf-8-sig") as f:
    out = csv.writer(f)
    out.writerow(["id", "title", "author", "published_at", "likes", "saves", "comments", "url", "full_text", "images"])
    for n in notes:
        d = full.get(n["id"])
        m = (d or n)["metrics"]
        out.writerow([n["id"], n["title"], n["author"]["name"], n["published_at"], m["likes"], m["favorites"],
                      m["comments"], n["url"], d["text"] if d else "", " ".join(d["images"] or []) if d else ""])
```

`utf-8-sig` lets Excel open the file with the Chinese intact. Ten search pages and 20 full notes would be $0.60.

## Good to know

- **No view counts.** Xiaohongshu does not show views publicly, so `metrics.views` is null and `meta.unavailable` gives `platform` as the reason. Saves (`favorites`) are the best signal of a note people want to keep.
- **Times are UTC.** `published_at` is ISO 8601 in UTC; add eight hours for Beijing time.
- **Note links.** `url` is the plain `xiaohongshu.com/explore/<id>` link. Opened in a browser without a token it may not load; [the xsec_token answer](https://okdata.online/answers/xiaohongshu-xsec-token/) explains why and what to do.
- **Deleted is free.** A note removed between search and detail returns `not_found` and is not charged.
- **Retries without paying twice.** Send an `Idempotency-Key` header with each call. The same request with the same key within 24 hours returns the stored answer with `meta.replayed: true` and no new charge.
- **Images are links.** Download the ones you need soon after the run; image links can stop working after a while.

For what a search costs at volume, see [the Xiaohongshu note search price](https://okdata.online/answers/xiaohongshu-note-search-api-price/). To go from these notes to what readers say under them, read the comments with [Xiaohongshu note comments](https://okdata.online/apis/xiaohongshu/notes/comments/list/).

## What the example costs

Three pages of the latest image notes for 露营 (camping), then full text and images of the 5 notes with the most saves

| Endpoint | Calls | Price | Subtotal |
|---|---|---|---|
| [Xiaohongshu note search](https://okdata.online/apis/xiaohongshu/notes/search/) | 3 | $0.02 | $0.06 |
| [Xiaohongshu note detail](https://okdata.online/apis/xiaohongshu/notes/get/) | 5 | $0.02 | $0.10 |
| Total | 8 |  | $0.16 |

Prices in force when this page was built. A failed call costs nothing.

## In your AI (MCP)

Connect the MCP server once, then say what you want. The agent finds these endpoints, reads their prices and calls them on your balance.

Say: Search Xiaohongshu for the latest image notes about 露营 (camping), three pages. Give me a table of every note with title, author, likes, saves, comments and link, and add the full text and image links for the 5 notes with the most saves.

```json
{
  "endpoint": "xiaohongshu.notes.search",
  "params": {
    "query": "防晒霜 推荐"
  },
  "idempotency_key": "<a new UUID>"
}
```

MCP: `https://api.okdata.online/mcp`

## Endpoints in this guide

- [Xiaohongshu note search](https://okdata.online/apis/xiaohongshu/notes/search/) `xiaohongshu.notes.search`: $0.02 per call · about 20 notes per page
- [Xiaohongshu note detail](https://okdata.online/apis/xiaohongshu/notes/get/) `xiaohongshu.notes.get`: $0.02 per call

## More about Xiaohongshu (RedNote)

- [Xiaohongshu (RedNote) API](https://okdata.online/apis/xiaohongshu/)
- [Xiaohongshu API in Python: notes, profiles and comments (2026)](https://okdata.online/guides/xiaohongshu-api-python/)
- [How to export Xiaohongshu comments for a keyword](https://okdata.online/guides/xiaohongshu-note-comments/)
- [How to shortlist Xiaohongshu PGY creators by rate and reads](https://okdata.online/guides/xiaohongshu-pgy-creator-rates/)
- [Xiaohongshu returns error 300011 (account abnormal). How do I keep collecting notes?](https://okdata.online/answers/xiaohongshu-300011-account-abnormal/)
- [Why does my Xiaohongshu scraper get status 461, and how do I get the data anyway?](https://okdata.online/answers/xiaohongshu-461-status-code/)
- [How do I find complaints about a brand on Xiaohongshu?](https://okdata.online/answers/xiaohongshu-brand-complaints/)
- [How can an AI agent outside China read Xiaohongshu instead of being sent to RedNote?](https://okdata.online/answers/xiaohongshu-data-for-agents-outside-china/)
- [How do I monitor a keyword on Xiaohongshu and collect new notes every day?](https://okdata.online/answers/xiaohongshu-keyword-monitoring-new-notes/)
- [How do I run a Xiaohongshu MCP on a cloud server without a browser?](https://okdata.online/answers/xiaohongshu-mcp-docker-server-timeout/)
- [Scraping it yourself vs a per-call data API: cost, upkeep and risk](https://okdata.online/compare/scraping-vs-data-api/)
- [How to choose a social media data API (2026)](https://okdata.online/compare/social-media-data-apis/)
- [MCP servers for social media data: self-hosted vs hosted](https://okdata.online/compare/social-media-data-mcp-servers/)
- [Xiaohongshu data APIs: official, third-party or open-source (2026)](https://okdata.online/compare/xiaohongshu-data-apis/)
