# Douyin Scraper (抖音) - Creator Profiles, Videos and Comments (`dami_studio/douyin-scraper`) Actor

Douyin (抖音) creators and their videos, single videos, comments, danmaku, collections, sounds and search suggestions as rows: followers, likes, comments, shares, saves, captions, hashtags, sounds, covers and links. Paste creator or video links, or v.douyin.com share links.

- **URL**: https://apify.com/dami_studio/douyin-scraper.md
- **Developed by:** [Dami's Studio](https://apify.com/dami_studio) (community)
- **Categories:** Social media, Videos
- **Security:** Limited permissions
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.02 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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 scraper for creator profiles, their videos and the comments under them**: paste Douyin creator, video,
collection or sound links and get one row each, with followers, likes, comments, shares, saves, captions, hashtags,
the sound, the cover and the link. The cover, video and sound links point at Douyin's servers and expire, often within
a day, so copy what you want to keep.

| | |
|---|---|
| **Input** | Creator links, video links, collection links or sound links, v.douyin.com share links, or the ids |
| **Output** | One row per creator, video, comment, danmaku, collection, sound or search suggestion: counts, caption, hashtags, sound, cover, links |
| **Ceiling** | 200 links per list, 20,000 rows per run |
| **Account needed** | None from you |
| **Price** | $1.02 per 1,000 results plus $0.005 to start each run, the same on every plan. The free plan's $5 a month covers about 4,600 results in runs of 100 |

| Using an AI agent? | |
|---|---|
| Actor | `dami_studio/douyin-scraper` |
| Set one field | `profiles`, labelled "Creators" in the Console |
| Cap the bill | `maxTotalChargeUsd` on the run, for example `0.10`: it never charges past that |
| MCP, one link | `https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/douyin-scraper` |
| How often | Weekly, to follow how a creator's videos and their counts move |

### 🌏 中文说明

粘贴抖音博主主页链接、视频链接、合集链接或音乐链接（也支持v.douyin.com分享链接），每个博主、视频、评论、弹幕、合集、音乐或搜索联想词一行：粉丝数、点赞、评论、分享、收藏、文案、话题标签、背景音乐、封面和链接。博主会先给一行主页资料，再按时间从新到旧给出作品。

在`profiles`里填博主链接，点Start就行，不需要抖音账号。按条数收费，价格见上方表格。本工具不是抖音的官方产品，与抖音没有关联。

### 🔍 What Douyin Scraper does

Four kinds of link go in, plus keywords for search suggestions, and each gives its own rows.

**Creators.** A profile row (followers, following, likes received, video count, bio, verification, IP location), then
the creator's videos, newest first, pinned ones included unless you leave them out.

**Videos.** One row per video or photo post, from a link, a share link or the numeric id. Turn on **Comments per
video** and the comments under each one follow, in the order Douyin shows them, with the commenter's IP location.
**Danmaku per video** adds the comments that scroll across the video, each with the second it appears at.

**Collections.** Douyin's 合集. A row for the collection itself, then its videos in episode order.

**Sounds.** A row for the sound (how many videos use it, who made it), then videos that use it.

**Search suggestions.** Type keywords and get what Douyin's search box offers for each, in its order. Handy for
finding the words people actually search with.

Every count comes back as a whole number. Douyin writes 1.2万 in the app; here it is 12000.

### 📋 What data you get from each Douyin video

| What you get | Field |
|---|---|
| The video's id, its page and its share link | `id`, `url`, `shareUrl` |
| Video or photo post | `mediaType` |
| The caption and the title, as posted | `text`, `caption`, `title` |
| When it was posted, and its length | `createdAt`, `createTime`, `durationSeconds` |
| Likes, comments, shares, saves and recommends | `likes`, `comments`, `shares`, `saves`, `recommends` |
| Pinned, ad, or marked as made with AI | `isPinned`, `isAd`, `isAiGenerated` |
| Who posted it | `authorNickname`, `authorUniqueId`, `authorSecUid`, `authorId`, `authorFollowers`, `authorVerificationText` |
| Hashtags, tagged accounts and Douyin's own topic tags | `hashtags`, `hashtagIds`, `mentions`, `videoTags` |
| The sound | `musicId`, `musicTitle`, `musicAuthor`, `musicIsOriginal`, `musicUrl` |
| Cover, size and one playback link | `coverUrl`, `dynamicCoverUrl`, `width`, `height`, `videoPlayUrl` |
| The images of a photo post | `images` |
| The collection it belongs to, and which episode | `collectionId`, `collectionName`, `collectionEpisode` |
| What the creator allows | `allowDownload`, `allowDuet`, `allowStitch`, `allowComment`, `allowShare` |
| Chapters, a warning label, and the searches Douyin suggests under the video | `chapters`, `riskWarning`, `suggestedSearches` |
| Douyin's own type flags | `awemeType`, `groupId`, `isStory`, `isLifeItem`, `isImageBeat`, `isDuetSing` |
| Your copies of the images, when asked | `coverFile`, `imageFiles` |

Creator rows carry `followers`, `following`, `likesReceived`, `videos`, `signature`, `uniqueId`, `ipLocation`,
`verificationText` and `profileUrl`. Comment rows carry `text`, `likes`, `replies`, `ipLocation`, `authorNickname` and
`createdAt`. Danmaku rows carry `text`, `offsetSeconds` and `likes`; suggestion rows `keyword`, `suggestion` and `rank`.

### ▶️ How to scrape Douyin creators and videos

1. Open [Douyin Scraper](https://apify.com/dami_studio/douyin-scraper) and click **Try for free**.
2. Paste creator links into **Creators**, video links into **Videos**, or both.
3. Set **Videos per creator**, and **Comments per video** if you want comments.
4. Click **Start**.
5. Download the rows as JSON, CSV or Excel, or read them from the Apify API.

Run it with every list empty and you get one labelled sample row, and that run costs only its $0.005 start.

### 💰 How much does it cost to scrape Douyin videos?

**$1.02 per 1,000 results**, plus **$0.005 to start each run**, the same on every plan. A result is one row: a creator, a video, a comment, a danmaku, a
collection, a sound or a suggestion. On the free plan, the $5 Apify gives you each month covers about 4,600 results in runs of 100.

Not charged as results: the sample row, note rows, links that lead nowhere, videos your date filters leave out, and
duplicates within a run. A run that finds nothing still pays its $0.005 start.

### 📥 What you give it

| Field | Default | What it is |
|---|---|---|
| `profiles` | empty | Creator page links, v.douyin.com share links, or the creator id that starts with MS4wLjAB |
| `videosPerProfile` | `20` | How many of each creator's videos to return, newest first; `0` for the profile row only |
| `videos` | empty | Video or photo-post links, share links, or numeric video ids |
| `commentsPerVideo` | `0` | Comments under each video in `videos`, up to 5,000 |
| `danmakuPerVideo` | `0` | Danmaku on each video in `videos`, up to 5,000 |
| `collections` | empty | Collection links or numeric ids |
| `videosPerCollection` | `50` | Videos from each collection |
| `sounds` | empty | Sound links or numeric ids |
| `videosPerSound` | `20` | Videos that use each sound |
| `suggestionKeywords` | empty | Keywords to look up in Douyin's search box, up to 50 |
| `postedAfter` | none | Keep videos posted on or after this day, Beijing time, as `2026-10-01` |
| `postedBefore` | none | Keep videos posted on or before this day |
| `recentDays` | none | Keep videos from the last N days |
| `excludePinned` | `false` | Leave out the videos a creator pinned |
| `saveCovers` | `false` | Copy each cover into the run's storage |
| `saveImages` | `false` | Copy photo-post images into the run's storage |
| `maxResults` | `1000` | Stop after this many results in all |

A date written any other way, such as "2 weeks", stops the run before it fetches anything and says so in a free row.

```json
{
  "profiles": ["https://www.douyin.com/user/MS4wLjABAAAA_w1jcNvWS8o1FJDoNCIbaiaEXb4ePppdjfP4uNnkwRc"],
  "videosPerProfile": 20,
  "videos": ["https://www.douyin.com/video/7700933283403681062"],
  "commentsPerVideo": 50
}
```

### 📤 What you get back

A real video row from a run on 3 November 2026, from a newspaper's official account. Long links are trimmed.

```json
{
  "recordType": "video",
  "id": "7700933283403681062",
  "url": "https://www.douyin.com/video/7700933283403681062",
  "mediaType": "video",
  "text": "AI员工已经上岗了？#陶然论金",
  "createdAt": "2026-10-26T11:14:22.000Z",
  "durationSeconds": 48.6,
  "likes": 374,
  "comments": 2,
  "shares": 5,
  "saves": 6,
  "isPinned": false,
  "authorNickname": "经济日报视点",
  "authorUniqueId": "jjrbstb",
  "authorFollowers": 6870978,
  "authorVerificationText": "经济日报视点官方抖音号",
  "hashtags": ["陶然论金"],
  "videoTags": ["科技", "行业资讯", "互联网资讯"],
  "musicTitle": "@经济日报视点创作的原声",
  "coverUrl": "https://p3-pc-sign.douyinpic.com/tos-cn-i-dy/7f2a3cca...jpeg?x-expires=...",
  "videoPlayUrl": "https://v5-dy-ov-experiment.zjcdn.com/1ebf1ad4.../video/tos/cn/...",
  "source": "profile",
  "scrapedAt": "2026-11-03T08:44:24.760Z"
}
```

| Field | How to read it |
|---|---|
| `id` | Douyin's own id. Join runs on it. |
| `likes`, `comments`, `shares`, `saves` | Whole numbers. `null` when Douyin sent no figure, never a made-up zero. |
| `authorFollowers` | Filled on creators' videos from their profile row; on single videos when Douyin sends it. |
| `coverUrl`, `videoPlayUrl`, `musicUrl` | Links to Douyin's servers. They expire, often within a day; turn on `saveCovers` to keep covers. |
| `ipLocation` | The province Douyin prints on a creator or a comment, such as 河南. |
| `source` | Which list a video came from: `profile`, `video`, `collection` or `sound`. |
| `input` | The link you gave that produced the row. |

### 🧾 Reading the output

| Row | How to spot it | Charged |
|---|---|---|
| Creator | `recordType` is `profile` | yes |
| Video | `recordType` is `video` | yes |
| Comment or danmaku | `recordType` is `comment` or `danmaku` | yes |
| Collection or sound | `recordType` is `collection` or `sound` | yes |
| Search suggestion | `recordType` is `suggestion` | yes |
| Sample | it carries `_sample` | no |
| Note | `recordType` is `note`, with `ok: false` and an `errorCode` | no |

| Code | What it means |
|---|---|
| `NOT_FOUND` | No public creator, video, collection or sound answers to that link: deleted, private, or a wrong id |
| `NO_RESULTS` | Douyin's search box offers no suggestions for that keyword |
| `BAD_INPUT` | An entry isn't a Douyin link or id, or a number or date in the input is out of range |
| `NOT_SERVED` | This item was not served this run. Re-run it later |
| `TIME_LIMIT` | The run reached its time limit. Everything before the row is kept |
| `COST_LIMIT` | The maximum charge you set was reached before a result could be delivered |
| `UNEXPECTED_ERROR` | The run stopped early on an unexpected error. The rows before it are kept |

Filter on `recordType` and you have one table per kind. A note row never fails the run.

### 💡 What people use it for

- Brand teams watching a list of Douyin creators each week, joining runs on `id` to see which videos gained likes and
  saves.
- Anyone sizing up a creator before a sponsorship: followers, likes received, how often they post, and how their
  videos land.
- Reading what viewers actually say under a launch video, with the province each comment came from.
- Tracking a sound or a collection as it spreads.

One recipe for a weekly creator report:

1. Put the creators you follow into **Creators** and schedule the run weekly; join the weeks on `id`.
2. Keep the video rows where `likes` beats that creator's usual, and paste their `url` into **Videos** with **Comments
   per video** at 100.
3. Set the week's rows beside Douyin Hot Search Scraper's topics for the same days, to see which videos rode a trend.

### 🚧 What it does not do

- **No video or audio files.** `videoPlayUrl` and `musicUrl` are links to where Douyin keeps them. Nothing is
  downloaded; only covers and photo-post images are copied, and only when you ask.
- **No follower or following lists.**
- **Public content only.** Private, deleted and friends-only videos come back as a free `NOT_FOUND` row.
- It is not an official Douyin tool. Dami's Studio is independent and is not affiliated with or endorsed by Douyin, or by any other company named on this page.

### 🧭 Which Douyin scraper do you need?

| If you want | Use |
|---|---|
| Douyin creators, their videos, single videos and their comments | This one |
| What Douyin users are searching for right now | [Douyin Hot Search Scraper](https://apify.com/dami_studio/douyin-hot-search-scraper) |
| RedNote notes with likes and collects | [RedNote Scraper](https://apify.com/dami_studio/rednote-scraper) |
| Bilibili videos, leaderboards, uploaders and comments | [Bilibili Scraper](https://apify.com/dami_studio/bilibili-scraper) |
| Weibo posts, accounts and the hot list | [Weibo Scraper](https://apify.com/dami_studio/weibo-scraper) |
| The same job on TikTok | [TikTok Scraper](https://apify.com/dami_studio/tiktok-scraper) |

### ❓ Questions people ask

#### Do I need a Douyin account to scrape Douyin?

No. You paste links and run it. Nothing to log into and no cookie to copy.

#### Can I paste a share link from the Douyin app?

Yes. A v.douyin.com link, or the whole block of share text with the link inside it, both work.

#### Why don't the numbers match what I see in the app?

Counts move by the minute, and the app rounds them (1.2万). The rows carry the exact figure at the time of the run.
Open the video in a private browser window to compare like with like.

#### Can I call it from code or connect it to an AI assistant?

The [API tab](https://apify.com/dami_studio/douyin-scraper/api/python) has code for Python, JavaScript and the CLI.
MCP clients like Claude and ChatGPT use `https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/douyin-scraper`,
billed to your Apify account at the same price.

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("dami_studio/douyin-scraper").call(
    run_input={"profiles": ["https://www.douyin.com/user/MS4wLjABAAAA_w1jcNvWS8o1FJDoNCIbaiaEXb4ePppdjfP4uNnkwRc"], "videosPerProfile": 20},
    max_total_charge_usd=0.10,
)
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    if row.get("ok") is False:
        continue
    print(row["recordType"], row.get("text") or row.get("nickname"), row.get("likes"))
```

#### Is scraping Douyin legal?

The rows are public content, read the way a signed-out visitor sees it, with no account and nothing private.
Creator names and comments are personal data under GDPR, China's PIPL and similar laws, so keep only what you need.
Douyin's own terms still apply to what you do with the data. Apify's write-up on
[the legality of web scraping](https://blog.apify.com/is-web-scraping-legal/) is a good place to start, and we are
not lawyers.

### 🆘 If something breaks

Open an issue on the actor's Issues tab. Include the run id and the link that misbehaved, and say what you expected.

# Actor input Schema

## `profiles` (type: `array`):

Creator page links (douyin.com/user/...), v.douyin.com share links, or the long creator id that starts with MS4wLjAB. Each gives one profile row, then the creator's videos, newest first.

## `videosPerProfile` (type: `integer`):

How many of each creator's videos to return, newest first. 0 returns the profile row only.

## `videos` (type: `array`):

Video or photo-post links (douyin.com/video/..., douyin.com/note/...), v.douyin.com share links, or the numeric video id. One video row each.

## `commentsPerVideo` (type: `integer`):

Comments to return under each video in Videos, in the order Douyin shows them. 0 returns none.

## `danmakuPerVideo` (type: `integer`):

Danmaku (the comments that scroll across the video) to return for each video in Videos, from the start of the video onward, with the second each one appears at. 0 returns none.

## `collections` (type: `array`):

Collection links (douyin.com/collection/...) or the numeric collection id. One collection row each, then its videos in episode order.

## `videosPerCollection` (type: `integer`):

How many videos to return from each collection. 0 returns the collection row only.

## `sounds` (type: `array`):

Sound links (douyin.com/music/...) or the numeric sound id. One sound row each, then videos that use it.

## `videosPerSound` (type: `integer`):

How many videos that use each sound to return. 0 returns the sound row only.

## `suggestionKeywords` (type: `array`):

Keywords to look up in Douyin's search box. Each gives the suggestions the box offers for it, in its order, one row each. Up to 50 keywords.

## `postedAfter` (type: `string`):

Keep only videos posted on or after this day (Beijing time). Applies to creators', collections' and sounds' videos. Filtered-out videos are not charged.

## `postedBefore` (type: `string`):

Keep only videos posted on or before this day (Beijing time). Filtered-out videos are not charged.

## `recentDays` (type: `integer`):

Keep only videos posted in the last N days. Works with the dates above; the later start wins.

## `excludePinned` (type: `boolean`):

Skip the videos a creator pinned to the top of their page.

## `saveCovers` (type: `boolean`):

Copy each returned video's cover image into this run's storage and add its link as coverFile. Run storage expires with the run.

## `saveImages` (type: `boolean`):

Copy the images of photo posts into this run's storage and add their links as imageFiles.

## `maxResults` (type: `integer`):

The run stops after this many charged rows in all. Note rows are free and don't count.

## Actor input object example

```json
{
  "profiles": [
    "https://www.douyin.com/user/MS4wLjABAAAA_w1jcNvWS8o1FJDoNCIbaiaEXb4ePppdjfP4uNnkwRc"
  ],
  "videosPerProfile": 20,
  "commentsPerVideo": 0,
  "danmakuPerVideo": 0,
  "videosPerCollection": 50,
  "videosPerSound": 20,
  "excludePinned": false,
  "saveCovers": false,
  "saveImages": false,
  "maxResults": 1000
}
```

# Actor output Schema

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

One row per creator profile, video, comment, collection or sound, told apart by recordType. Free note rows (ok: false) say what was not returned and why.

## `report` (type: `string`):

What the run was asked for, how many rows each link gave, and why the run stopped.

## `files` (type: `string`):

Video covers and photo-post images, when Save video covers or Save photo-post images is on.

# 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 = {
    "profiles": [
        "https://www.douyin.com/user/MS4wLjABAAAA_w1jcNvWS8o1FJDoNCIbaiaEXb4ePppdjfP4uNnkwRc"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("dami_studio/douyin-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 = { "profiles": ["https://www.douyin.com/user/MS4wLjABAAAA_w1jcNvWS8o1FJDoNCIbaiaEXb4ePppdjfP4uNnkwRc"] }

# Run the Actor and wait for it to finish
run = client.actor("dami_studio/douyin-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 '{
  "profiles": [
    "https://www.douyin.com/user/MS4wLjABAAAA_w1jcNvWS8o1FJDoNCIbaiaEXb4ePppdjfP4uNnkwRc"
  ]
}' |
apify call dami_studio/douyin-scraper --silent --output-dataset

```

## MCP server setup

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