# Douyin Profile Scraper (`khadinakbar/douyin-profile-scraper`) Actor

Scrape public Douyin (抖音) creator profiles by URL, share-link, sec\_user\_id, or uid. Returns nickname, bio, follower/following/like counts, verification, region, gender, custom badges. No cookies. MCP-ready. $0.007 per profile.

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

## Pricing

from $7.00 / 1,000 profile 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

## Douyin Profile Scraper

Scrape public **Douyin (抖音)** creator profiles by profile URL, share-link, or `sec_user_id`. Returns one flat record per creator with identity, audience metrics, verification badges, region, and business signals. Optional recent-posts enrichment.

> Owned Camoufox (anti-detect Firefox) + Apify Residential proxy with country rotation HK → SG → TW → JP → MO. No login, no cookies you have to manage. MCP-ready for AI agents.

### What you get

| Field | Description |
|---|---|
| `nickname` | Display name (昵称) |
| `signature` | Bio / signature (个人简介) |
| `secUserId` | Stable Douyin opaque user id |
| `uid` | Numeric user id |
| `shortId` | Public Douyin handle (抖音号) |
| `followerCount` | Followers (粉丝数) |
| `followingCount` | Following (关注数) |
| `totalFavorited` | Total likes received (获赞数) |
| `awemeCount` | Total video count |
| `verified` | Verified flag |
| `customVerify` | Verification badge text |
| `enterpriseVerifyReason` | Enterprise / brand verification reason |
| `gender` | male / female / unknown |
| `ipLocation` | IP location (IP属地) |
| `country` / `province` / `city` | Geo fields when set |
| `isLiveCommerce` | Live-commerce enabled |
| `withCommerceEntry` | Has commerce store |
| `avatarUrl` | Avatar URL |
| `profileUrl` | Public profile URL |

When `includeRecentPosts: true` is set, post records are appended with `itemType: "post"` carrying `awemeId`, `postDesc`, engagement stats, `playCount`, `videoDurationSec`, and `postUrl`.

### When to use

- KOL / creator research on Chinese-market influencers.
- Brand monitoring of verified Douyin accounts and enterprise pages.
- Influencer-marketing lead lists.
- AI agents profiling Chinese creators for outreach or due-diligence.

### When NOT to use

- TikTok (global) — use a TikTok-specific actor.
- Private / locked accounts (Douyin does not expose them).
- Numeric uid lookups (Douyin's public web requires `sec_user_id` to load a profile page).

### Inputs

| Field | Type | Description |
|---|---|---|
| `profileInputs` | string\[] | Profile URLs, share-links, or raw `sec_user_id`s (auto-detected per row). |
| `includeRecentPosts` | boolean | Default `false`. When `true`, scrolls the profile feed and grabs recent videos. |
| `maxPostsPerProfile` | int | Default `20`, max `200`. |
| `maxProfiles` | int | Default `25`, max `100`. Cost cap. |
| `proxyConfiguration` | object | Default Apify Residential, country HK. Override only if you have a better CN-region pool. |

Accepted `profileInputs` row formats:

```
https://www.douyin.com/user/MS4wLjABAAAAVtZkS6ZpJVm-T1FZW5XWGcVTQ-Z2u7CcEt1MdJxoZbA
https://v.douyin.com/iJxYZ8k/
MS4wLjABAAAAVtZkS6ZpJVm-T1FZW5XWGcVTQ-Z2u7CcEt1MdJxoZbA
```

### Pricing

| Event | Price |
|---|---|
| Actor start | $0.00005 |
| Profile scraped | **$0.007** per profile |
| Post scraped | **$0.003** per recent post (only when `includeRecentPosts=true`) |

Typical run of 10 profiles ≈ **$0.07**. Same 10 with 20 recent posts each ≈ **$0.67**.

### Reliability

Douyin is a hostile anti-bot target (JS challenge wall + a\_bogus signing + IP geo cross-check). Camoufox + Apify Residential clears it most of the time, but expect:

- **HK → SG → TW → JP → MO** automatic country rotation per blocked navigation.
- **Cookie warmup** on `douyin.com` homepage before the profile page (sets `ttwid`).
- \~85-92% observed success rate on typical input distributions. Failures are logged and pushed as `{ _error, input, secUserId }` rows so partial datasets are still useful.

If you have a higher-quality CN-region residential pool, supply it via `proxyConfiguration.proxyUrls` for better results.

### Output example

```json
{
  "itemType": "profile",
  "input": "https://www.douyin.com/user/MS4wLjABAAAAVtZkS6ZpJVm-T1FZW5XWGcVTQ-Z2u7CcEt1MdJxoZbA",
  "secUserId": "MS4wLjABAAAAVtZkS6ZpJVm-T1FZW5XWGcVTQ-Z2u7CcEt1MdJxoZbA",
  "uid": "93847265012",
  "shortId": "douyin_handle",
  "nickname": "示例创作者",
  "signature": "短视频每天更新",
  "followerCount": 1284321,
  "followingCount": 248,
  "totalFavorited": 18950221,
  "awemeCount": 532,
  "verified": true,
  "customVerify": "美食博主",
  "gender": "female",
  "ipLocation": "上海",
  "isLiveCommerce": true,
  "avatarUrl": "https://...",
  "profileUrl": "https://www.douyin.com/user/MS4w...",
  "scrapedAt": "2026-06-27T06:55:12.000Z",
  "_proxyCountry": "HK"
}
```

### MCP usage

```
search-actors → "douyin profile"
call-actor    → khadinakbar/douyin-profile-scraper
get-actor-output → filter itemType=profile
```

The actor returns flat, semantic keys ≤500 tokens/record — built for agent consumption.

### FAQ

**Why no `uid` or 抖音号 (short\_id) input?** Douyin's public web routes require `sec_user_id` to render a profile page. Supplying a numeric uid alone has no public conversion path that survives without a paid signing API.

**What happens on a hard block?** The row is pushed with `_error: "profile_xhr_not_captured"` and the next input attempt rotates country. If every input is blocked across every country, the run honest-fails so the failure shows up in your Apify metrics instead of silently succeeding with zero data.

**Do video URLs expire?** Yes. Douyin video CDN URLs expire within ~1 hour; avatar/cover URLs last longer but are not guaranteed.

### Legal

This actor scrapes only publicly visible Douyin profile information. Use complies with Douyin's terms and your local regulations. Do not use scraped data to harass creators or violate privacy laws.

### Related actors

- [tiktok-profile-scraper](https://apify.com/khadinakbar/tiktok-profile-scraper) — global TikTok equivalent.
- [tiktok-video-comments-scraper](https://apify.com/khadinakbar/tiktok-video-comments-scraper) — TikTok comments.
- [douyin-search-scraper](https://apify.com/khadinakbar/douyin-search-scraper) — Douyin keyword search.

# Actor input Schema

## `profileInputs` (type: `array`):

Douyin profile identifiers. Accepted: full profile URL ('https://www.douyin.com/user/MS4w...'), short share-link ('https://v.douyin.com/xyz/'), or raw sec\_user\_id (starts with 'MS4w'). One per row. NOT for TikTok handles, numeric uids, or 抖音号 short\_ids — Douyin's public web requires sec\_user\_id to resolve a profile page.

## `includeRecentPosts` (type: `boolean`):

If true, scroll the profile feed and intercept up to 'maxPostsPerProfile' recent video posts per profile (separate dataset rows tagged itemType='post'). Default false to keep runs fast and cheap. Adds $0.003 per post pushed.

## `maxPostsPerProfile` (type: `integer`):

Cap on recent video posts pulled per profile. Ignored when 'includeRecentPosts' is false. Bounded 1-200. Default 20.

## `maxProfiles` (type: `integer`):

Hard cap on profiles processed this run, after dedup. Acts as a cost-cap. Bounded 1-100. Default 25.

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

Default uses Apify Residential proxies with country rotation HK → SG → TW → JP → MO (Douyin is geo-sensitive; mainland CN IPs are not in the Apify Residential pool, so HK/Asia neighbors are the fastest viable path). Override only if you have a higher-quality CN-region residential pool.

## Actor input object example

```json
{
  "profileInputs": [
    "https://www.douyin.com/user/MS4wLjABAAAAVtZkS6ZpJVm-T1FZW5XWGcVTQ-Z2u7CcEt1MdJxoZbA",
    "MS4wLjABAAAAVtZkS6ZpJVm-T1FZW5XWGcVTQ-Z2u7CcEt1MdJxoZbA"
  ],
  "includeRecentPosts": false,
  "maxPostsPerProfile": 20,
  "maxProfiles": 25,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "HK"
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

Full dataset of profile and post records.

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

Per-run counters + provider stats stored in OUTPUT.

# 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 = {
    "profileInputs": [
        "https://www.douyin.com/user/MS4wLjABAAAAVtZkS6ZpJVm-T1FZW5XWGcVTQ-Z2u7CcEt1MdJxoZbA"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "HK"
    }
};

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

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

```

## MCP server setup

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