# Douyin Scraper (`natanielsantos/douyin-scraper`)

This powerful tool enables you to extract data from Douyin, the Chinese version of TikTok. Use it to scrape post data, like URLs, numbers of followers, hearts, video, music-related data and more. Download Douyin data as a HTML, JSON, CSV, Excel, or XML doc.

- **URL**: https://beta-securitybyobscurity.apify.com/natanielsantos/douyin-scraper.md
- **Developed by:** [Nataniel Santos](https://beta-securitybyobscurity.apify.com/natanielsantos) (community)
- **Categories:** Social media, Automation, Videos
- **Stats:** 470 total users, 45 monthly users, 99.2% runs succeeded, 15 bookmarks
- **User rating**: No ratings yet

## Pricing

$35.00/month + usage

To use this Actor, you pay a monthly rental fee to the developer. The rent is subtracted from your prepaid usage every month after the free trial period.
You also pay for the Apify platform usage, which gets cheaper the higher Apify subscription plan you have.

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

# README

## What does Douyin Scraper do?

Douyin Scraper is a tool that enables you to scrape video data from the Douyin (Chinese TikTok). This is a ready-to-use scraping tool and doesn't require any programming knowledge to get started. Douyin Scraper allows you to:

- Get posts from chosen **hashtags** or **search terms**.
- Get posts including details: name, ID, bio, followers/following numbers, etc.
- Get individual **video posts** by using specific video URLs.
- Get **video** and **music-related data**.

## How much will scraping Douyin cost you?

When it comes to scraping, it can be challenging to estimate the resources needed to extract data as use cases may vary significantly. That's why the best course of action is to run a test scrape with a small sample of input data and limited output. You’ll get your price per scrape, which you’ll then multiply by the number of scrapes you intend to do.

## Input parameters

If this actor is run on the Apify platform, our simple interface should help you out in configuring all the parameters. This scraper accept the following input fields:

- `searchTermsOrHashtags` - scrapes Douyin posts by search terms or hashtags. You can scrape one or several search terms or hashtags at the same time.
- `postUrls` - scrapes specific Douyin posts. You can scrape one or several posts simultaneously.
- `maxItemsPerUrl` - sets up the amount of results you expect to be scraped for each URL.
- `shouldDownloadVideos` - Choose whether or not download videos and replace the original play URL with a link to the video stored on the Key-Value Store.
- `shouldDownloadCovers` - Choose whether or not download covers and replace the original cover URL with a link to the cover stored on the Key-Value Store.

Please note that only one of the following must be set: `searchTermsOrHashtags`, or `postUrls`, not both at the same time.

## Example Output

```json
{
  "id": "7296149517517212980",
  "text": "cute cats.:D#小咪会赶走你一天的疲惫 #喵星人",
  "createTime": 1698767202,
  "createDate": "2023-08-11",
  "thumb": "https://p9-pc-sign.douyinpic.com/tos-cn-i-0813c001/ogBDmIvOEfWACyQCMBznbAM9DsAeAASgASslI5~noop.jpeg?x-expires=1700596800&x-signature=k8o35CYFUDKhiiausDhDLKhRoIE%3D&from=3213915784&s=PackSourceEnum_SEARCH&se=false&biz_tag=pcweb_cover&l=20231108042539C059CD838A92B3375B32",
  "url": "https://www.douyin.com/video/7296149517517212980",
  "authorMeta": {
    "id": "101823080930",
    "secUid": "MS4wLjABAAAACvVkl3ZfT849YzNrTzxj3lDeWwxBFZFSYX7i_jLE8rw",
    "name": "Chandler",
    "username": "",
    "verified": false,
    "signature": ":-D",
    "avatarThumb": "https://p3-pc.douyinpic.com/aweme/100x100/aweme-avatar/tos-cn-i-0813c001_o4yF8yADNACtALzAAwtqmNIg2feBXdtAUNhEAE.jpeg?from=116350172",
    "avatarLarge": "https://p3-pc.douyinpic.com/aweme/1080x1080/aweme-avatar/tos-cn-i-0813c001_o4yF8yADNACtALzAAwtqmNIg2feBXdtAUNhEAE.jpeg?from=116350172",
    "followingCount": 0,
    "followersCount": 0,
    "heartCount": 0
  },
  "musicMeta": {
    "id": "7275161107433244674",
    "name": "麦当劳汉堡（正版授权版）",
    "author": "小pa",
    "album": "麦当劳汉堡（正版授权）",
    "isOriginal": false,
    "duration": 16
  },
  "videoMeta": {
    "cover": "https://p9-pc-sign.douyinpic.com/tos-cn-i-0813c001/ogBDmIvOEfWACyQCMBznbAM9DsAeAASgASslI5~noop.jpeg?x-expires=1700596800&x-signature=k8o35CYFUDKhiiausDhDLKhRoIE%3D&from=3213915784&s=PackSourceEnum_SEARCH&se=false&biz_tag=pcweb_cover&l=20231108042539C059CD838A92B3375B32",
    "originCover": "https://p3-pc-sign.douyinpic.com/tos-cn-i-0813c001/ogBDmIvOEfWACyQCMBznbAM9DsAeAASgASslI5~noop.jpeg?x-expires=1700596800&x-signature=g8b6UZkjdBMtb2qfpJpJtrNXnyg%3D&from=3213915784&s=PackSourceEnum_SEARCH&se=false&biz_tag=pcweb_cover&l=20231108042539C059CD838A92B3375B32",
    "width": 720,
    "playUrl": "https://sf9-sign.douyinstatic.com/tos-cn-ve-2774/os7Zzhg4IxkEARtNMB2VVQfDOerDkBt0DHCchq?x-expires=1699475139&x-signature=l%2FK1%2BGQt26k%2FJ0UYRp8yfIri4so%3D"
  },
  "statistics": {
    "diggCount": 1,
    "shareCount": 1,
    "commentCount": 1,
    "collectCount": 0
  },
  "mentions": [],
  "hashtags": [
    {
      "id": "1768145161646092",
      "name": "小咪会赶走你一天的疲惫"
    },
    {
      "id": "1560122388542465",
      "name": "喵星人"
    }
  ]
}
```

## Integrations and Douyin Scraper

Douyin Scraper can be connected with almost any cloud service or web app thanks to [integrations on the Apify platform](https://apify.com/integrations). You can integrate with Make, Zapier, Slack, Airbyte, GitHub, Google Sheets, Google Drive, [and more](https://docs.apify.com/integrations). Or you can use [webhooks](https://docs.apify.com/integrations/webhooks) to carry out an action whenever an event occurs, e.g. get a notification whenever Douyin Scraper successfully finishes a run.

## Using Douyin Scraper with the Apify API

The Apify API gives you programmatic access to the Apify platform. The API is organized around RESTful HTTP endpoints that enable you to manage, schedule, and run Apify actors. The API also lets you access any datasets, monitor actor performance, fetch results, create and update versions, and more.

To access the API using Node.js, use the apify-client NPM package. To access the API using Python, use the apify-client PyPI package.

Check out the [Apify API reference](https://docs.apify.com/api/v2) docs for full details or click on the [API tab](https://apify.com/natanielsantos/douyin-scraper/api) for code examples.

## Personal data

You should be aware that your results might contain personal data. Personal data is protected by GDPR in the European Union and other laws and regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers. You can read the basics of ethical web scraping in our blog post on the [legality of web scraping](https://blog.apify.com/is-web-scraping-legal/).

## Your feedback

We’re always working on improving the performance of our Actors. So if you’ve got any technical feedback for Douyin scraper or simply found a bug, please create an issue on the Actor’s [Issues tab](https://console.apify.com/actors/uudPCDtUwsNp6n9ib/issues) in Apify Console.

# Actor input Schema

## `searchTermsOrHashtags` (type: `array`):

List of search terms or hashtags you want to scrape. For example `#chinesetiktok` or `anime edit`.

## `maxItemsPerUrl` (type: `integer`):

Maximum number of items you want to scrape per hashtag or profile.

## `postUrls` (type: `array`):

Should be a list of post URLs you want to scrape.

## `shouldDownloadVideos` (type: `boolean`):

Whether to download Douyin video files. Note that this will increase time required for the scrape.

## `shouldDownloadCovers` (type: `boolean`):

Whether or not to download the video covers.

## `maxDownloadSize` (type: `integer`):

Maximum size in megabytes of the video that will be stored in Key-Value store. Videos larger than this won't be downloaded.

## `storageName` (type: `string`):

Name of the Key-Value Store where the videos and covers will be stored. Note that if you leave this empty, an unnamed Key-value store will be created and eventually deleted (keeping time depends on your plan).

## Actor input object example

```json
{
  "searchTermsOrHashtags": [
    "#chinesetiktok",
    "anime edit"
  ],
  "maxItemsPerUrl": 50,
  "shouldDownloadVideos": false,
  "shouldDownloadCovers": false,
  "maxDownloadSize": 50,
  "storageName": "mydouyinvideos"
}
```

# 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 = {
    "searchTermsOrHashtags": [
        "dogs"
    ],
    "maxItemsPerUrl": 50,
    "maxDownloadSize": 50,
    "storageName": "mydouyinvideos"
};

// Run the Actor and wait for it to finish
const run = await client.actor("natanielsantos/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 = {
    "searchTermsOrHashtags": ["dogs"],
    "maxItemsPerUrl": 50,
    "maxDownloadSize": 50,
    "storageName": "mydouyinvideos",
}

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

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

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

```

## CLI example

```bash
echo '{
  "searchTermsOrHashtags": [
    "dogs"
  ],
  "maxItemsPerUrl": 50,
  "maxDownloadSize": 50,
  "storageName": "mydouyinvideos"
}' |
apify call natanielsantos/douyin-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=natanielsantos/douyin-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Douyin Scraper",
        "description": "This powerful tool enables you to extract data from Douyin, the Chinese version of TikTok. Use it to scrape post data, like URLs, numbers of followers, hearts, video, music-related data and more. Download Douyin data as a HTML, JSON, CSV, Excel, or XML doc.",
        "version": "0.5",
        "x-build-id": "SVBqURphM4deTv0fX"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/natanielsantos~douyin-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-natanielsantos-douyin-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/natanielsantos~douyin-scraper/runs": {
            "post": {
                "operationId": "runs-sync-natanielsantos-douyin-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/natanielsantos~douyin-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-natanielsantos-douyin-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "searchTermsOrHashtags": {
                        "title": "Search Terms or Hashtags",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "List of search terms or hashtags you want to scrape. For example `#chinesetiktok` or `anime edit`.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxItemsPerUrl": {
                        "title": "Max number of posts per search term/hashtag",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Maximum number of items you want to scrape per hashtag or profile.",
                        "default": 0
                    },
                    "postUrls": {
                        "title": "Post URLs",
                        "type": "array",
                        "description": "Should be a list of post URLs you want to scrape.",
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "shouldDownloadVideos": {
                        "title": "Should Download Videos",
                        "type": "boolean",
                        "description": "Whether to download Douyin video files. Note that this will increase time required for the scrape.",
                        "default": false
                    },
                    "shouldDownloadCovers": {
                        "title": "Should Download Covers",
                        "type": "boolean",
                        "description": "Whether or not to download the video covers.",
                        "default": false
                    },
                    "maxDownloadSize": {
                        "title": "Don't download videos larger than",
                        "type": "integer",
                        "description": "Maximum size in megabytes of the video that will be stored in Key-Value store. Videos larger than this won't be downloaded.",
                        "default": 50
                    },
                    "storageName": {
                        "title": "Name your storage",
                        "type": "string",
                        "description": "Name of the Key-Value Store where the videos and covers will be stored. Note that if you leave this empty, an unnamed Key-value store will be created and eventually deleted (keeping time depends on your plan)."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
