Scrapers

TikTok trends

Tracks TikTok For You feed, hashtag velocity, sound velocity, and search results. Uses a real browser with in-page webmssdk signing for the X-Bogus header. Writes one item per video to the dataset.

Updated today

Overview

At a glance
Worker
ultron-tiktok-trends
Runtime
Playwright Chromium, headless by default
Modes
recommend, challenge, music, search
Signing
X-Bogus computed in-page via webmssdk
Cap
500 items per target
Proxy
Residential proxy, country matches the region knob
Default delay
2500 ms per signed fetch, +50% jitter

TikTok defenses are the most aggressive in the social fleet. Every endpoint requires the X-Bogus header, which is computed from the request body via a JS shim TikTok ships into every page. The actor lets the browser compute it natively rather than reimplementing the algorithm.

Four modes

ModeInputsSurface
recommend(none beyond region)The For You feed. Useful for tracking what is rising right now in a region.
challengehashtags[] (no #)Hashtag landing page. Per hashtag, scroll-paginate up to maxItemsPerTarget.
musicmusicIds[] (numeric)Sound landing page. Tracks creators who used a given sound.
searchsearchQueries[]Keyword search results. Each query is a separate iteration.

Input schema

.actor/INPUT_SCHEMA.jsonjson
1{
2 "mode": "recommend", // recommend | challenge | music | search
3 "hashtags": ["food", "gaming"], // challenge mode
4 "musicIds": ["6919...."], // music mode
5 "searchQueries": ["AI agents"], // search mode
6 "maxItemsPerTarget": 50, // 1 to 500
7 "region": "US", // ISO 3166-1 alpha-2, also sets proxy country
8 "proxyConfiguration": {
9 "useApifyProxy": true,
10 "apifyProxyGroups": ["RESIDENTIAL"],
11 "apifyProxyCountry": "US"
12 },
13 "requestDelayMs": 2500,
14 "headless": true
15}

Request signing

Every TikTok API call needs an X-Bogus header.

src/sign.py (concept)py
1# 1. Navigate the browser to https://www.tiktok.com/ once. TikTok injects
2# webmssdk.js into the page; it exposes window.byted_acrawler.frontierSign().
3# 2. For each outgoing API call:
4# a. Build the query string we will send.
5# b. Call page.evaluate("(qs) => window.byted_acrawler.frontierSign(qs)", qs)
6# to compute X-Bogus.
7# c. Attach X-Bogus to the request, fire via the browser context (so
8# cookies + IP match what TikTok expects).
9# 3. The browser holds the session indefinitely. We never reload after the
10# initial nav unless TikTok flags us (in which case the actor aborts).
Note
Reimplementing X-Bogus outside the browser is possible but fragile. The shim changes when TikTok pushes a new web bundle, and the in-browser approach picks the new algorithm up with zero changes on our side.

Crawl flow

src/__main__.pypy
1# 1. Boot Playwright Chromium with the residential proxy bound at the
2# browser level (not socket level - TikTok checks TLS fingerprint via JS).
3# 2. Navigate to https://www.tiktok.com/, accept cookie banner if present.
4# 3. For each target:
5# a. Build the API URL for the mode.
6# b. Sign via the in-page webmssdk shim.
7# c. Fetch via page.evaluate(fetch(...)) so cookies + IP match.
8# d. Parse the JSON response into dataset rows.
9# e. Paginate via cursor until maxItemsPerTarget or empty.
10# 4. Sleep requestDelayMs + 50% jitter between requests.
11# 5. On 429 or empty-with-redirect, abort the run.

Output shape

dataset-row.jsonjson
1{
2 "kind": "video",
3 "source": "tiktok",
4 "capturedFrom": "challenge:food", // recommend | challenge:<tag> | music:<id> | search:<query>
5 "videoId": "7234982734987234",
6 "authorUsername": "creator-handle",
7 "authorName": "Display Name",
8 "caption": "trying out the new ...",
9 "viewCount": 1284322,
10 "likeCount": 89321,
11 "commentCount": 2342,
12 "shareCount": 1042,
13 "musicTitle": "original sound - creator-handle",
14 "musicId": "691900000000000",
15 "publishedAt": "2026-05-18T14:00:00Z",
16 "videoUrl": "https://v16-webapp...",
17 "scrapedAt": "2026-05-19T12:00:00Z"
18}

Webhook contract

actor.jsonjson
1{
2 "eventTypes": ["ACTOR.RUN.SUCCEEDED", "ACTOR.RUN.FAILED", "ACTOR.RUN.TIMED_OUT", "ACTOR.RUN.ABORTED"],
3 "requestUrl": "https://scraper-webhook.51ultron.com/apify",
4 "payload": { "actorName": "tiktok-trends", "source": "tiktok", "datasetId": "<id>" }
5}

File map

actors/tiktok-trends
.actor
actor.json
INPUT_SCHEMA.json
src
__main__.pybrowser boot + per-mode dispatchers
sign.pyin-page X-Bogus signer wrapper
Dockerfile
requirements.txt
README.md