TikTok Comments Scraper
Pricing
from $30.00 / 1,000 results
TikTok Comments Scraper
Scrape the comments of one or MANY TikTok videos in a single run. Returns text, author, likes, thread structure (parent/reply) and the source video itself. No login, no cookies — uses a real browser so TikTok signs its own API requests.
Pricing
from $30.00 / 1,000 results
Rating
0.0
(0)
Developer
code craker
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
12 days ago
Last modified
Categories
Share
Apify actor that scrapes the comments of one or many TikTok videos in a single run and exports them as structured data.
This actor drives a real Chrome (Playwright) so TikTok's own JavaScript signs its
API requests, then intercepts the /api/comment/list/ (and
/api/comment/list/reply/) responses — the same browser-interception pattern as the
Reddit and YouTube comment scrapers.
⚠️ A logged-in session is required
Unlike TikTok's public hashtag/search feeds (which our
tiktok-post-search-scraper reads logged-out), the comment endpoint is
auth-gated. For a logged-out guest, TikTok answers /api/comment/list/ with an
empty HTTP 200 body no matter how clean the exit IP is — verified across many
fresh residential IPs. The video's comment panel then silently falls back to the
"You may like" tab and no comments load. This is the same gating we found on
Facebook comments.
So provide a logged-in TikTok session via the cookies input (export it with a
"Get cookies.txt" / EditThisCookie-style browser extension while signed in to
tiktok.com). With a session the comment API returns real data; without one, a run
still succeeds but collects only the source video(s) and 0 comments, logging a
clear warning. For a fully hands-off option, use a vendor
(clockworks/tiktok-comments-scraper) that maintains accounts server-side, and keep
this actor as the session-backed fallback (see Integration below).
Features
- Batched: pass many video URLs and they are all scraped in ONE run
(
maxCommentsapplies per video). Results are pushed after each video, so an abort keeps everything collected so far. - Any video reference works:
tiktok.com/@user/video/<id>, photo posts, or a bare numeric video id. (Shortvm.tiktok.comlinks are not supported — use the full URL.) - Replies included with thread structure (
parentCommentId+replyLevel), or top-level comments only (includeReplies: false). - The source video is emitted too (flagged
is_source_post: true) with caption, author and engagement counts; disable withincludeSourcePost: false. - Anti-detection built in: stealth fingerprint, residential-proxy preflight, and relaunch on a fresh IP with a per-video retry when TikTok serves a captcha / empty responses.
Input
{"urls": ["https://www.tiktok.com/@nasa/video/7401234567890123456","https://www.tiktok.com/@bbc/video/7409999999999999999"],"maxComments": 100,"includeReplies": true,"includeSourcePost": true,"region": "US","cookies": [ { "name": "sessionid", "value": "…", "domain": ".tiktok.com", "path": "/" } ],"proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "US" }}
cookies accepts the exported cookie array (objects with name/value/domain)
or a raw name=value; name2=value2 Cookie-header string. It is optional but
strongly recommended — see the session note above.
startUrls ([{ "url": ... }]) is accepted as an alternative to urls.
resultsLimit and maxReplies are accepted as aliases for maxComments.
Output
One dataset item per comment. Every item carries videoId / aweme_id /
videoWebUrl / postUrl / postId / inputUrl, so comments from a multi-video run
are always attributable to their source video.
{"id": "7500000000000000001","cid": "7500000000000000001","text": "First! love this","createTimeISO": "2026-07-01T09:30:12.000Z","diggCount": 152, "likesCount": 152,"replyCommentTotal": 3, "repliesCount": 3,"uniqueId": "fan1","author": {"name": "Fan One", "username": "fan1", "id": "111","profileUrl": "https://www.tiktok.com/@fan1", "avatar": "https://a/av.jpg"},"videoId": "7401234567890123456","aweme_id": "7401234567890123456","videoWebUrl": "https://www.tiktok.com/@nasa/video/7401234567890123456","parentCommentId": null,"repliesToId": null,"replyLevel": 0,"isReply": false,"postId": "7401234567890123456","inputUrl": "https://www.tiktok.com/@nasa/video/7401234567890123456","is_source_post": false}
parentCommentIdisnullfor a top-level comment; otherwise the id of the comment it replies to. TikTok reply ids point at the parent (nested replies point at the reply they answer).createTimeISOis exact — TikTok exposes real comment timestamps.
Integration (scraping-tool)
Drop-in for the existing TikTok comment path — the output matches the
clockworks/tiktok-comments-scraper shape that saveCommentsWithPostLink() and
_matchCommentToPost() already read (cid, text, createTimeISO, diggCount,
replyCommentTotal, uniqueId, videoWebUrl, aweme_id, repliesToId).
Because the comment endpoint is auth-gated (see the session note above), make the
vendor the primary (it maintains accounts server-side, so it needs no session
from us) and use this actor as the session-backed fallback — the same
arrangement as the Facebook comment path. When you have a maintained TikTok session
in the store, pass it as cookies.
// ACTOR_FALLBACKS in scrapingService.js — vendor primary, ours as the fallback'clockworks/tiktok-comments-scraper': 'outspoken_strategy/tiktok-comments-scraper',
// scrapingService.scrapeCommentsBatch — tiktok branch} else if (actor === 'outspoken_strategy/tiktok-comments-scraper') {delete input.startUrls;input.urls = urls;input.maxComments = cappedComments(input.maxComments ?? resultsLimit);input.includeSourcePost = input.includeSourcePost ?? false;input.includeReplies = input.includeReplies ?? false; // match FB: top-level onlyinput.cookies = input.cookies ?? getTikTokSessionCookies(); // required: comment API is auth-gatedinput.proxyConfiguration = input.proxyConfiguration ?? { useApifyProxy: true, apifyProxyGroups: ['RESIDENTIAL'], apifyProxyCountry: 'US' };}
_postMatchKey('tiktok', videoWebUrl) extracts the id via /\/video\/(\d+)/, and
every comment also carries videoId/aweme_id — so attribution works unchanged.
Local development
npm installecho '{ "urls": ["https://www.tiktok.com/@tiktok/video/7106594312292453675"], "maxComments": 30, "proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "US" } }' > storage/key_value_stores/default/INPUT.jsonnpm start
TikTok flags IPs that make many requests, so local runs from a home IP may be served
empty responses — the actor is designed to run on Apify residential proxies. Deploy
with apify push. Remember that without a cookies session the comment API returns
empty bodies (see the session note at the top), so a cookie-less run will collect
only the source video(s).