# Douyin Comments Scraper - Video Comment Threads & Replies (`khadinakbar/douyin-comments-scraper`) Actor

Scrape public Douyin (抖音) video comments and nested replies from URLs, share links, or aweme IDs. Use for China-market social listening and agents needing one flat row per comment. Not for video metadata or TikTok (see sibling Actors). Returns text, likes, author, IP 属地, parent id. $0.003/comment.

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

## Pricing

from $3.00 / 1,000 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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Douyin Comments Scraper

Turn a public Douyin (抖音) video URL, share link, or numeric aweme ID into a flat dataset of visible comment and reply rows. Paste the identifiers you already have and get comment text, likes, author identity, IP 属地 when Douyin shows it, and parent linkage for nested replies.

This Actor is for China-market social listening teams, KOL agencies, and AI agents that need public comment threads before they branch into video metadata or creator profile workflows.

Referenced by: `.actor/actor.json` → `"readme": "../README.md"`. User instruction: "Build a Douyin comments scraper apify actor".

### Best fit for this Actor

- Collect public comment sentiment on known Douyin campaign creatives.
- Export reply threads under viral posts for moderation or research review.
- Feed MCP or CRM workflows with one predictable row per comment or reply.

Use this Actor when you already have Douyin video URLs, share links, or aweme IDs and need public comments.

Do not use this Actor for video metadata, keyword search, creator profiles, Shop products, or global TikTok. For video stats, start with [Douyin Video Scraper](https://apify.com/khadinakbar/douyin-video-scraper). For keyword discovery, use [Douyin Search Scraper](https://apify.com/khadinakbar/douyin-search-scraper). For creator identity, use [Douyin Profile Scraper](https://apify.com/khadinakbar/douyin-profile-scraper). Global TikTok comments belong on [TikTok Video Comments Scraper](https://apify.com/khadinakbar/tiktok-video-comments-scraper).

### Practical scenario

A brand analyst pastes `https://www.douyin.com/video/7577614489533680959`, keeps `maxComments` at `20`, and leaves `includeReplies` on. The run returns flat rows: top-level comments plus nested replies with `isReply=true` and `parentCommentId`. A captcha-walled residential route finishes `FAILED` with `UPSTREAM_FAILED` and zero `comment-scraped` charges. A public video with an empty comment panel finishes `SUCCEEDED` with `VALID_EMPTY`.

### Quick start input

```json
{
  "videoUrls": ["https://www.douyin.com/video/7577614489533680959"],
  "maxComments": 20,
  "includeReplies": true
}
```

`videoUrls` accepts canonical `/video/{id}` links, `v.douyin.com` share links, `iesdouyin.com/share/video/{id}` URLs, or a bare 15–21 digit aweme ID.

### Input reference

| Field | Type | What it controls |
|---|---|---|
| `videoUrls` | array (required) | Public Douyin video URLs, share links, or aweme IDs. Max 20 unique values. |
| `maxComments` | integer | Hard cap per video after dedupe. Default 50, max 500. |
| `maxVideos` | integer | Hard cap on videos this run. Default 5, max 20. |
| `includeReplies` | boolean | Include nested replies as flat rows. Default true. |
| `proxyConfiguration` | object | Defaults to Apify Residential HK. Override only with a CN-capable residential pool. |

### What data you receive

One dataset item is one public Douyin comment or reply.

```json
{
  "commentId": "7432109876543210987",
  "text": "好看！",
  "likeCount": 12,
  "replyCount": 2,
  "createTime": "2025-09-04T13:53:20.000Z",
  "ipLabel": "上海",
  "authorNickname": "Viewer",
  "authorProfileUrl": "https://www.douyin.com/user/MS4wLjABAAAAexample",
  "isReply": false,
  "awemeId": "7577614489533680959",
  "videoUrl": "https://www.douyin.com/video/7577614489533680959",
  "scrapedAt": "2026-09-19T12:00:00.000Z",
  "provider": "camoufox"
}
```

| Field | Meaning |
|---|---|
| `commentId` + `text` | Stable comment id and visible body |
| `likeCount` / `replyCount` | Public engagement counters when Douyin exposes them |
| `isReply` / `parentCommentId` | Nested reply linkage |
| `ipLabel` | Public IP 属地 label when shown |
| `authorNickname` / `authorProfileUrl` | Public commenter identity |
| `scrapedAt` / `provider` | Collection time (ISO 8601) and Camoufox route |

`OUTPUT` and `RUN_SUMMARY` in the default key-value store hold `outcome`, `itemsPushed`, and `chargedEventCounts`.

### Use through the API

```bash
curl -X POST "https://api.apify.com/v2/acts/khadinakbar~douyin-comments-scraper/runs" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"videoUrls":["https://www.douyin.com/video/7577614489533680959"],"maxComments":20}'
```

### MCP / agent prompt card

```
Use khadinakbar/douyin-comments-scraper with videoUrls set to one Douyin
/video/{id} URL or aweme ID. Keep maxComments at 20 for a cheap probe.
Expect one flat row per public comment/reply. Route TikTok URLs to
tiktok-video-comments-scraper instead. Charge is $0.003 per saved comment.
```

### Pricing

Pay per event + platform usage pass-through:

| Event | Price |
|---|---|
| `apify-actor-start` | $0.00005 |
| `comment-scraped` | $0.003 per saved comment or reply |

Invalid inputs and captcha-blocked zero-row runs do not charge `comment-scraped`. Platform compute and Residential proxy usage are billed to the run user.

### Honest limits

- Public web comments only. No login, no private messages, no Shop reviews, no liker identities.
- ScrapeCreators and SociaVault have no Douyin comment routes; runtime is owned Camoufox.
- Mainland CN IPs are not in Apify Residential; HK→SG→TW→JP→MO rotation may still hit captcha.
- Nested replies depend on what Douyin exposes in the public panel / reply XHR.

### Legal / responsible use

Only scrape public Douyin content you are allowed to process. Respect Douyin's terms, applicable privacy law, and your own compliance policy. This Actor is not affiliated with Douyin or ByteDance.

### Builder's note

Douyin signs comment list requests with `msToken` / `a_bogus`, so passive browser intercept after homepage warmup is more reliable than forging the query string. Prefer known video URLs from the video sibling over raw search — search pages captcha more aggressively than `/video/{id}` detail pages.

# Changelog

This Actor's version history is a separate document: https://apify.com/khadinakbar/douyin-comments-scraper/changelog.md

# Actor input Schema

## `videoUrls` (type: `array`):

Douyin videos whose public comments you want. Accepts https://www.douyin.com/video/7577614489533680959, https://v.douyin.com/iAbc123/ share links, iesdouyin.com share URLs, or a bare 15–21 digit aweme ID. One value per row. Default empty is rejected. NOT a profile URL, search keyword, or TikTok link — use douyin-profile-scraper, douyin-search-scraper, or tiktok-video-comments-scraper instead.

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

Hard cap on comment+reply rows collected per video after dedupe. Acts as a cost cap at $0.003/row. Bounded 1–500. Default 50. Does not raise Douyin's public visibility — private or captcha-walled videos still return no billed rows.

## `maxVideos` (type: `integer`):

Hard cap on unique videos processed this run after dedupe. Bounded 1–20. Default 5.

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

When true (default), nested reply previews and reply-list XHR rows are saved as flat dataset items with isReply=true and parentCommentId. When false, only top-level comments are billed. Reply collection still depends on what Douyin exposes on the public web view.

## `proxyConfiguration` (type: `object`):

Default uses Apify Residential with country rotation HK → SG → TW → JP → MO. Douyin is geo-sensitive and mainland CN IPs are not in the Apify Residential pool. Override only if you have a higher-quality CN-region residential pool. Not a Douyin login cookie field.

## Actor input object example

```json
{
  "videoUrls": [
    "https://www.douyin.com/video/7577614489533680959",
    "7577614489533680959"
  ],
  "maxComments": 50,
  "maxVideos": 5,
  "includeReplies": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "HK"
  }
}
```

# Actor output Schema

## `comments` (type: `string`):

One row per public Douyin comment or reply with text, likes, author, and parent linkage.

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

Detailed diagnostics, proxy country, failure reasons, and estimated PPE cost.

## `output` (type: `string`):

Compact machine contract: outcome, message, itemsPushed, chargedEventCounts.

# 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 = {
    "videoUrls": [
        "https://www.douyin.com/video/7577614489533680959"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "HK"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("khadinakbar/douyin-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 = {
    "videoUrls": ["https://www.douyin.com/video/7577614489533680959"],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "HK",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("khadinakbar/douyin-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 '{
  "videoUrls": [
    "https://www.douyin.com/video/7577614489533680959"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "HK"
  }
}' |
apify call khadinakbar/douyin-comments-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,khadinakbar/douyin-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/HYRa8lA4QEsakRGdO/builds/HeA61IGAlOOYVyXPd/openapi.json
