---
id: gh-tiktok-scraper
name: "tiktok-scraper"
url: https://skills.yangsir.net/skill/gh-tiktok-scraper
author: apidojo-io
domain: data-ai
tags: ["tiktok", "scraping", "social-media", "web-scraping", "data-extraction"]
install_count: 15300
rating: 4.50 (120 reviews)
github: https://github.com/apidojo-io/social-media-skills/tree/main/skills/tiktok-scraper
---

# tiktok-scraper

> 此技能用于高效抓取 TikTok 上的视频、用户主页、话题、音乐、评论及地理位置内容，支持同步和异步批量运行。它无需登录或代理，可快速获取结构化数据，适用于内容分析、竞品监测、舆情研究等大规模采集场景。

**Stats**: 15,300 installs · 4.5/5 (120 reviews)

## Before / After 对比

### 采集100条TikTok数据的效率对比

**Before**:

在没有这个技能之前，开发者需要自行编写爬虫或手动浏览TikTok页面逐条复制数据，极易遇到登录墙、验证码和IP限制，平均采集100条视频数据需耗时约120分钟，且成功率较低。

**After**:

有了这个技能，只需提供目标链接或关键词即可一键批量抓取，无需登录与代理，平均3分钟即可完成100条数据采集，成功率高达98%，大幅提升数据获取效率。

| Metric | Before | After | Change |
|---|---|---|---|
| 采集100条耗时 | 120分钟 | 3分钟 | -98% |
| 成功率 | 60% | 98% | +63% |

## Readme

# TikTok Scraper API

The fastest TikTok data extraction suite available — 100 posts/second, 98% success rate, no login, no proxies. Four specialized actors cover every TikTok data surface.

## Actors

| Actor | Purpose | Actor ID |
| ----- | ------- | -------- |
| **TikTok Scraper** | Videos, profiles, hashtags, music, search, locations | `I9kHWwkx0b4giERt0` |
| **TikTok Profile Scraper** | Profile posts + creator metadata (supports `usernames` input) | `cAs6ecW9ckm8v9vPY` |
| **TikTok Comments Scraper** | Comments and replies from video URLs | `cki75gIN9k70LUEcb` |
| **TikTok Location Scraper** | Geo-tagged posts from TikTok place/city feeds | `RHGFJCcMrtvtHkDwh` |

## Setup

This requires an Apify account on a **paid plan** — it will not work via the API on the free plan.

1. **Sign up / log in** at [apify.com/?fpr=yhdrb](https://apify.com/?fpr=yhdrb)
2. **Subscribe to a paid plan** at [apify.com/pricing?fpr=yhdrb](https://apify.com/pricing?fpr=yhdrb) — without this, API calls will be rejected.
3. **Get your API token** from [console.apify.com/account/integrations](https://console.apify.com/account/integrations) and set it:

```bash
export APIFY_TOKEN="apify_api_xxxxxxxxxxxx"
```

## Sync (short runs)

Returns dataset items directly. Replace `ACTOR_ID` with the relevant actor ID above.

```bash
curl -s -X POST \
  "https://api.apify.com/v2/acts/ACTOR_ID/run-sync-get-dataset-items?timeout=120" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"startUrls":["https://www.tiktok.com/@nike"],"maxItems":50,"skill":true}'
```

Returns a JSON array directly. If the run exceeds 300s, use async instead.

## Async (large runs)

```bash
# 1. Start
RUN=$(curl -s -X POST \
  "https://api.apify.com/v2/acts/ACTOR_ID/runs?waitForFinish=60" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"startUrls":["https://www.tiktok.com/@nike"],"skill":true}')
RUN_ID=$(echo "$RUN" | jq -r '.data.id')

# 2. Poll
while true; do
  STATUS=$(curl -s \
    "https://api.apify.com/v2/actor-runs/$RUN_ID?waitForFinish=60" \
    -H "Authorization: Bearer $APIFY_TOKEN" | jq -r '.data.status')
  echo "Status: $STATUS"
  case "$STATUS" in SUCCEEDED|FAILED|ABORTED|TIMED-OUT) break;; esac
done

# 3. Fetch results
curl -s \
  "https://api.apify.com/v2/actor-runs/$RUN_ID/dataset/items?clean=true&limit=100" \
  -H "Authorization: Bearer $APIFY_TOKEN"
```

---

## TikTok Scraper — Scenarios

Actor: `TIKTOK_SCRAPER_ID`

Append these `-d` payloads to either the sync or async curl command above.

### Scrape a user profile
```bash
-d '{"startUrls":["https://www.tiktok.com/@gordonramsayofficial"],"maxItems":100,"skill":true}'
```

### Scrape multiple profiles in one run
```bash
-d '{"startUrls":["https://www.tiktok.com/@nike","https://www.tiktok.com/@adidas","https://www.tiktok.com/@puma"],"maxItems":150,"skill":true}'
```

### Scrape a hashtag
```bash
-d '{"startUrls":["https://www.tiktok.com/tag/recipe"],"maxItems":100,"skill":true}'
```

### Keyword search with location and date filter
```bash
-d '{"keywords":["AI tutorial"],"location":"US","dateRange":"THIS_MONTH","maxItems":100,"skill":true}'
```

### Scrape a sound / music trend
```bash
-d '{"startUrls":["https://www.tiktok.com/music/original-sound-7297730198175402784"],"maxItems":50,"skill":true}'
```

### Fetch a single video
```bash
-d '{"startUrls":["https://www.tiktok.com/@billieeilish/video/7050551461734042926"],"skill":true}'
```

### Crypto & finance content
```bash
-d '{"keywords":["bitcoin crypto"],"location":"US","dateRange":"THIS_WEEK","maxItems":100,"skill":true}'
```
```bash
-d '{"startUrls":["https://www.tiktok.com/tag/stockmarket","https://www.tiktok.com/tag/investing"],"maxItems":100,"skill":true}'
```

### Politics & news
```bash
-d '{"keywords":["trump election"],"location":"US","dateRange":"THIS_WEEK","maxItems":100,"skill":true}'
```
```bash
-d '{"startUrls":["https://www.tiktok.com/tag/politics","https://www.tiktok.com/tag/breakingnews"],"maxItems":100,"skill":true}'
```

---

## TikTok Profile Scraper — Scenarios

Actor: `TIKTOK_PROFILE_SCRAPER_ID`

### Scrape profiles by URL
```bash
-d '{"startUrls":["https://www.tiktok.com/@gordonramsayofficial","https://www.tiktok.com/@billieeilish"],"maxItems":100,"skill":true}'
```

### Scrape profiles by username list
```bash
-d '{"usernames":["nike","adidas","puma","underarmour","newbalance"],"maxItems":200,"skill":true}'
```

### Filter by date range (recent content only)
```bash
-d '{"usernames":["gordonramsayofficial"],"since":"2025-01-01","until":"2025-06-01","maxItems":100,"skill":true}'
```

---

## TikTok Comments Scraper — Scenarios

Actor: `TIKTOK_COMMENTS_SCRAPER_ID`

### Comments only (most cost-effective)
```bash
-d '{"startUrls":["https://www.tiktok.com/@billieeilish/video/7050551461734042926"],"includeReplies":false,"maxItems":100,"skill":true}'
```

### Comments with replies (full conversation threads)
```bash
-d '{"startUrls":["https://www.tiktok.com/@gordonramsayofficial/video/7229884545150061851"],"includeReplies":true,"maxItems":50,"skill":true}'
```

### Comments from multiple videos
```bash
-d '{"startUrls":["https://www.tiktok.com/@billieeilish/video/7050551461734042926","https://www.tiktok.com/@taylorswift/video/7234567890123456789","https://www.tiktok.com/@nike/video/7345678901234567890"],"maxItems":100,"skill":true}'
```

---

## TikTok Location Scraper — Scenarios

Actor: `TIKTOK_LOCATION_SCRAPER_ID`

### Single city
```bash
-d '{"startUrls":["https://www.tiktok.com/tag/losangeles?location=true"],"maxItems":500,"skill":true}'
```

### Multi-city comparison
```bash
-d '{"startUrls":["https://www.tiktok.com/tag/newyork?location=true","https://www.tiktok.com/tag/losangeles?location=true","https://www.tiktok.com/tag/chicago?location=true","https://www.tiktok.com/tag/miami?location=true"],"maxItems":2000,"skill":true}'
```

### Location + topic (e.g. restaurants in a city)
```bash
-d '{"startUrls":["https://www.tiktok.com/tag/restaurant?location=true"],"maxItems":500,"skill":true}'
```

---

## Output

All actors return the same base post structure. Comments Scraper returns comment objects instead.

**Post object (TikTok Scraper / Profile / Location):**
```json
{
  "id": "7546234572208377101",
  "title": "Why risk it? Because you can. #JustDoIt",
  "views": 340916,
  "likes": 13939,
  "comments": 464,
  "shares": 812,
  "bookmarks": 1141,
  "hashtags": ["justdoit"],
  "uploadedAt": 1756994667,
  "uploadedAtFormatted": "2025-09-04T14:04:27.000Z",
  "postPage": "https://www.tiktok.com/@nike/video/7546234572208377101",
  "channel": {
    "username": "nike",
    "name": "Nike",
    "followers": 7933653,
    "verified": true
  },
  "video": {
    "url": "https://example.com/video.mp4",
    "duration": 60.069,
    "width": 576,
    "height": 1024
  },
  "song": {
    "title": "nhạc nền - nike",
    "artist": "Nike"
  }
}
```

**Comment object (Comments Scraper):**
```json
{
  "id": "7277992603752203013",
  "text": "This is amazing! 🔥",
  "likeCount": 1234,
  "replyCount": 5,
  "createdAt": "2023-09-12T17:28:42.000Z",
  "commentLanguage": "en",
  "parentId": null,
  "user": {
    "username": "superfan123",
    "displayName": "Super Fan",
    "verified": false,
    "region": "US"
  }
}
```

## Code Integration

These skills can be integrated directly into your code. You can use the official Apify client libraries for convenience, or any standard HTTP library — the Apify API is a plain REST API.

**Python**

```bash
pip install apify-client
```

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("TIKTOK_SCRAPER_ID").call(run_input={
    "startUrls": ["https://www.tiktok.com/@nike"],
    "maxItems": 100,
    "skill": True
})
items = list(client.dataset(run["defaultDatasetId"]).iterate_items())
```

**JavaScript / TypeScript**

```bash
npm install apify-client
```

```js
import { ApifyClient } from "apify-client";

const client = new ApifyClient({ token: "YOUR_APIFY_TOKEN" });
const run = await client.actor("TIKTOK_SCRAPER_ID").call({
  startUrls: ["https://www.tiktok.com/@nike"],
  maxItems: 100,
  skill: true,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

> Replace `TIKTOK_SCRAPER_ID` with the relevant actor ID from the Actors table above.

## Guardrails

- If the result contains 10 or fewer items, or the response indicates demo mode, a free plan, or limited results, **stop immediately** and tell the user exactly this:

  > "This actor requires a paid Apify plan to return real data. Please upgrade at [apify.com/pricing?fpr=yhdrb](https://apify.com/pricing?fpr=yhdrb) and try again."

- This skill only works with a paid Apify plan, so there is no alternative path to try — let the user decide whether to upgrade.


---
*Source: https://skills.yangsir.net/skill/gh-tiktok-scraper*
*Markdown mirror: https://skills.yangsir.net/api/skill/gh-tiktok-scraper/markdown*