# Xiaohongshu (RedNot) Comments Scraper (`khadinakbar/xiaohongshu-comments-scraper`) Actor

Extract Xiaohongshu (RedNote / 小红书) comment threads and nested replies from public note URLs or note IDs. Returns one flat row per comment or reply with commenter identity, text, likes, IP location, and timestamps. Cookieless; no Xiaohongshu login required.

- **URL**: https://apify.com/khadinakbar/xiaohongshu-comments-scraper.md
- **Developed by:** [Khadin Akbar](https://apify.com/khadinakbar) (community)
- **Categories:** Social media, Automation, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 xiaohongshu comment scrapeds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Xiaohongshu Comments Scraper

Extract **comment threads and nested replies** from public [Xiaohongshu](https://www.xiaohongshu.com) (RedNote / 小红书 / Little Red Book) notes. Paste a note URL or 24-character note ID and get one flat dataset row per comment or reply: commenter name, profile URL, text, likes, IP 属地, and the timestamp Xiaohongshu shows. No Xiaohongshu login or cookies.

This Actor is built for brand-monitoring teams, China-market researchers, and AI agents that already have a note URL and need the public conversation under it. Use it for comment threads on a known note. For keyword discovery, start with the search sibling linked below.

### Best fit for this Actor

- You have public Xiaohongshu **note URLs** (explore, discovery/item, or profile/note) or `xhslink.com` share links and want the comment thread.
- You need **flat rows** (one comment or reply per item) for spreadsheets, CRM, or an agent, including `parentCommentId` for replies.
- Start with [Xiaohongshu Search Scraper](https://apify.com/khadinakbar/xiaohongshu-search-scraper) when you only have a keyword, then pass each note URL here to collect the comments.

### Brand-monitoring workflow: from one viral note to a comment export

A social-listening analyst tracking an official Xiaohongshu governance announcement pastes the public explore URL (with `xsec_token`) into `noteUrls`, leaves `includeReplies` on, and sets `maxComments` to 50. The run returns commenter names, profile URLs, comment text, like counts, IP cities such as 上海 / 北京, and reply threading. They then schedule the same note URL weekly, compare new `commentId` values, and export the dataset to CSV for sentiment tagging.

### Quick start input

```json
{
  "noteUrls": [
    "https://www.xiaohongshu.com/explore/69afda73000000002800b3f2?xsec_token=ABS294BN1RIZ1_yaXpYLmp_VZQ_na4j9mhGzLPMICzCIU="
  ],
  "maxComments": 5,
  "includeReplies": true
}
```

`maxComments` is a run-wide cap that counts top-level comments and nested replies together so an agent can bound spend before calling.

### Input reference

| Field | Type | What it controls |
|---|---|---|
| `noteUrls` | array (required) | Explore, discovery/item, user/profile/{user}/{note}, xhslink.com, or bare 24-character note IDs. Prefer URLs that include `xsec_token`. |
| `maxComments` | integer | Cap on saved rows including replies. Default 50, automated-test prefill 5, max 2000. |
| `includeReplies` | boolean | Save nested replies as their own rows. Default true. |
| `maxRepliesPerComment` | integer | Cap replies under one parent. Default 20. `0` takes every reply currently expanded on the public page. |

### What data you receive

Each dataset item is one public comment or nested reply.

| Field | Description |
|---|---|
| `noteId`, `noteUrl`, `resolvedNoteUrl`, `noteTitle` | Source note |
| `noteCommentCount` | Total comments Xiaohongshu reports on the note |
| `commentId`, `parentCommentId`, `isReply`, `threadDepth`, `replyToUser` | Threading |
| `commentText` | Public comment body |
| `commenterName`, `commenterUserId`, `commenterProfileUrl`, `commenterAvatar` | Commenter identity |
| `likeCount`, `replyCount`, `ipLocation` | Engagement and IP 属地 |
| `createdAt`, `commentPosition`, `scrapedAt`, `provider` | Time, rank, provenance |

```json
{
  "noteId": "69afda73000000002800b3f2",
  "noteUrl": "https://www.xiaohongshu.com/explore/69afda73000000002800b3f2?xsec_token=ABS294BN1RIZ1_yaXpYLmp_VZQ_na4j9mhGzLPMICzCIU=",
  "noteTitle": "关于打击AI托管运营账号的治理公告",
  "commentId": "69b00725000000000c03176a",
  "parentCommentId": null,
  "isReply": false,
  "threadDepth": 0,
  "commentText": "哈哈，终于出手了！",
  "commenterName": "peace",
  "commenterUserId": "5ff81b730000000001002e21",
  "commenterProfileUrl": "https://www.xiaohongshu.com/user/profile/5ff81b730000000001002e21",
  "likeCount": 1000,
  "ipLocation": "上海",
  "createdAt": "03-10",
  "commentPosition": 1,
  "provider": "scrapfly"
}
```

You can download the dataset as JSON, CSV, Excel, or HTML from the run's Output tab.

### Public-data contract

- **Public comments.** The Actor reads what Xiaohongshu renders on a public note page: commenter identity, text, likes, IP 属地, and nested replies that are already expanded.
- **Share URLs work best.** Prefer explore/discovery URLs that include `xsec_token`, or `xhslink.com` share links. Xiaohongshu often serves an anti-bot bounce for bare note IDs and token-less links.
- **Visible thread.** Rows come from the public comment panel after a bounded scroll. `noteCommentCount` tells you how large the thread is; `maxComments` caps what this run saves.
- **Timestamps stay as shown.** Relative strings such as `4小时前` or `03-10` are stored as Xiaohongshu displays them. Empty optional fields are omitted.

### Pricing

Pay per event (PPE) plus platform usage. Confirm the live prices on the Actor **Pricing** tab before a large run — the Pricing tab is the current source of truth.

| Event | What it bills |
|---|---|
| `apify-actor-start` | $0.00005 when the run starts |
| `comment-scraped` | $0.003 per saved comment or reply row |

Example: 1 note, 20 comments (including replies) ≈ $0.00005 + (20 × $0.003) = **$0.06005** in PPE, plus platform usage for the fetch. Set `maxComments` so an agent can forecast the ceiling.

### How to run from the API

```bash
curl "https://api.apify.com/v2/acts/khadinakbar~xiaohongshu-comments-scraper/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"noteUrls":["https://www.xiaohongshu.com/explore/69afda73000000002800b3f2?xsec_token=ABS294BN1RIZ1_yaXpYLmp_VZQ_na4j9mhGzLPMICzCIU="],"maxComments":5,"includeReplies":true}'
```

Or with ApifyClient:

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('khadinakbar/xiaohongshu-comments-scraper').call({
  noteUrls: [
    'https://www.xiaohongshu.com/explore/69afda73000000002800b3f2?xsec_token=ABS294BN1RIZ1_yaXpYLmp_VZQ_na4j9mhGzLPMICzCIU=',
  ],
  maxComments: 5,
  includeReplies: true,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

### Agent prompt card

> Scrape public Xiaohongshu (RedNote) comments for this note URL. Use `khadinakbar/xiaohongshu-comments-scraper`. Pass `noteUrls` as the full explore URL including `xsec_token` when you have it. Set `maxComments` to the spend ceiling (each row costs $0.003). Read `OUTPUT.outcome` and `itemsPushed` after the run: `COMPLETE` means the visible thread was saved, `VALID_EMPTY` means the note has no public comments, `INVALID_INPUT` means the URL was not a note, and `UPSTREAM_FAILED` means Xiaohongshu blocked the page. Return commenterName, commentText, ipLocation, isReply, parentCommentId, likeCount, and the source noteUrl. This is a read-only public-data scrape with no login side effects.

### Best results

- Provide a **specific public note URL** with `xsec_token`, or an `xhslink.com` share link, rather than a profile URL or a keyword.
- Pair this Actor with [Xiaohongshu Search Scraper](https://apify.com/khadinakbar/xiaohongshu-search-scraper) when you need to discover notes first, then collect comments.
- For TikTok comment threads instead of Xiaohongshu, use [TikTok Comments Scraper](https://apify.com/khadinakbar/tiktok-video-comments-scraper).
- Validate `OUTPUT` / `RUN_SUMMARY` plus dataset rows so you can confirm comments landed.
- Keep `maxComments` tight on first runs so you can confirm the note is public before scaling.

This Actor is designed as a focused standalone workflow when you already have Xiaohongshu note URLs.

### Builder's note

I built this as a comments-only sibling to the existing Xiaohongshu search Actor after I found that ScrapeCreators and SociaVault still have no Xiaohongshu comment routes (live OpenAPI probe) and that raw HTTP to xiaohongshu.com bounces with an anti-bot interstitial. In my testing, the public comment panel is in the rendered DOM (`id="comment-…"`, `data-user-id`, IP 属地) even when `__INITIAL_STATE__.comments.list` stays empty. My goal was an MCP-ready flat row with parent/reply fields, matching the comment text people actually see on the note.

### Legal / responsible use

Use this Actor only on content you are authorized to collect. Respect Xiaohongshu's terms of service, applicable laws (including privacy rules in your jurisdiction), and the rights of commenters. This tool collects public page data and is not affiliated with, endorsed by, or connected to Xiaohongshu / Xingyin Information Technology (Shanghai) Co., Ltd. You are responsible for how you store and use the export.

# Actor input Schema

## `noteUrls` (type: `array`):

Public Xiaohongshu note references to scrape comments from. Accepts https://www.xiaohongshu.com/explore/{id}, /discovery/item/{id}, /user/profile/{userId}/{noteId}, https://xhslink.com/... share links, and bare 24-character note IDs. URLs that include xsec\_token work most reliably. Up to 50 notes per run. NOT profile-only URLs without a note ID, and not keyword search.

## `maxComments` (type: `integer`):

Hard cap on total dataset rows saved across all notes, counting top-level comments and nested replies together. Defaults to 50. Prefill 5 keeps the automated quality test under five minutes. Raise this to collect longer threads; each saved row is billed as comment-scraped.

## `includeReplies` (type: `boolean`):

When true (default), nested replies under each top-level comment are saved as their own rows with parentCommentId, isReply=true, and threadDepth=1. Set false to save only top-level comments. This does not invent private reply data — only replies Xiaohongshu renders on the public note page.

## `maxRepliesPerComment` (type: `integer`):

Maximum nested replies to save under one top-level comment. Defaults to 20. Set 0 to take every reply currently expanded on the public page. Does not apply when includeReplies is false.

## Actor input object example

```json
{
  "noteUrls": [
    "https://www.xiaohongshu.com/explore/69afda73000000002800b3f2?xsec_token=ABS294BN1RIZ1_yaXpYLmp_VZQ_na4j9mhGzLPMICzCIU="
  ],
  "maxComments": 1,
  "includeReplies": true,
  "maxRepliesPerComment": 20
}
```

# Actor output Schema

## `results` (type: `string`):

Dataset items containing note context, commenter identity, comment text, likes, IP location, reply threading, and timestamps.

## `summary` (type: `string`):

Run summary including outcome, itemsPushed, per-note results, warnings, and billing counters.

## `runSummary` (type: `string`):

Machine-readable RUN\_SUMMARY record mirroring OUTPUT for integrations that read RUN\_SUMMARY directly.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "noteUrls": [
        "https://www.xiaohongshu.com/explore/69afda73000000002800b3f2?xsec_token=ABS294BN1RIZ1_yaXpYLmp_VZQ_na4j9mhGzLPMICzCIU="
    ],
    "maxComments": 1
};

// Run the Actor and wait for it to finish
const run = await client.actor("khadinakbar/xiaohongshu-comments-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "noteUrls": ["https://www.xiaohongshu.com/explore/69afda73000000002800b3f2?xsec_token=ABS294BN1RIZ1_yaXpYLmp_VZQ_na4j9mhGzLPMICzCIU="],
    "maxComments": 1,
}

# Run the Actor and wait for it to finish
run = client.actor("khadinakbar/xiaohongshu-comments-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "noteUrls": [
    "https://www.xiaohongshu.com/explore/69afda73000000002800b3f2?xsec_token=ABS294BN1RIZ1_yaXpYLmp_VZQ_na4j9mhGzLPMICzCIU="
  ],
  "maxComments": 1
}' |
apify call khadinakbar/xiaohongshu-comments-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,khadinakbar/xiaohongshu-comments-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/EyOr3ph0fcZIn4vDX/builds/NR2CRmLAEvaPekiu9/openapi.json
