TikTok Scraper - from $0.05 per 1,000 videos
Pricing
from $0.05 / 1,000 videos
TikTok Scraper - from $0.05 per 1,000 videos
From $0.05 per 1,000 videos. Track public TikTok profiles and hashtags day by day: views, likes, comments, shares and saves for every video, plus comment text and replies.
Pricing
from $0.05 / 1,000 videos
Rating
0.0
(0)
Developer
Esdrasdw
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
10 hours ago
Last modified
Categories
Share
๐ Track TikTok performance, day by day
$0.10 per 1,000 videos, and $0.05 on any paid Apify plan. About 30x cheaper than the usual TikTok scraper on the free plan.
A versatile, low-cost TikTok scraper for people who watch numbers: agencies, brands, creators and analysts who want to see how every video and every profile evolves, day after day. Views, likes, comments, shares and saves for each video, exact follower counts for each profile, and the comments themselves when you want to know what the audience is saying.
Give it a list of profiles or hashtags, run it on a schedule, and every run is a fresh snapshot you can compare with yesterday's. No login, no cookies, no browser automation on your side.
Why this scraper
- ๐ธ Cheap enough to run every day. $0.10 per 1,000 videos on the free plan, $0.05 on paid plans. Comments and replies are $0.05 per 1,000 ($0.025 on paid plans), and only when you ask for them.
- ๐ฏ High-quality data. Profile numbers are exact (1,881,247 followers, not "1.9M"). Every video comes with the same clean, structured fields, ready for a spreadsheet, a dashboard or a database.
- ๐ Built for tracking evolution. Schedule a daily run over your profiles and watch views, likes, comments, shares and saves grow video by video, and followers and total likes grow profile by profile.
- ๐งฐ Versatile. Up to 1,000 profiles and 100 hashtags per run, newest or oldest videos first, any date range (for an old period of a big profile the run jumps straight to it), comments with their replies, reposts, and only the columns you choose.
- ๐ก๏ธ You only pay for what you get. Charged per video and per comment delivered. A run that returns nothing costs nothing, and options this Actor does not offer are refused before anything is collected.
What you get
For every video: the link, the caption, hashtags and mentions, the publish date, view, like, comment, share, save and repost counts, and three organized blocks:
authorMeta: the profile, with nickname, bio, bio link, avatar, verified, account creation date, followers, following, friends, total likes and video count (exact numbers, not rounded).musicMeta: the sound, with name, author, original or not, duration and cover.videoMeta: duration, width, height, quality, format and cover.
Photo slideshows come with every photo, and the tagged location and effects come too. Turn on comments and each video carries its comments, each comment carrying its replies.
You choose the columns. Keep only the fields you need and you get clean columns instead of a wall of JSON you have to clean up later.
The layout follows the most used TikTok scraper on Apify, so switching doesn't break your integration.
How to use it
- In the Profiles block, add profiles: a handle (
nasa),@nasaor a profile URL (https://www.tiktok.com/@nasa). Set Videos per profile and pick Sort videos by: Latest or Oldest. - In the Hashtags block, add hashtags:
fyp,#fyporhttps://www.tiktok.com/tag/fyp, and set Videos per hashtag. Fill in profiles, hashtags or both. - Optionally, add Reposts under Profile sections.
- Optionally, set Comments per video and Replies per comment.
- Optionally, narrow it down under Date range.
- Optionally, pick the columns under Fields to return.
- Run it, then download the dataset as JSON, CSV, Excel or HTML.
Input
| Field | Type | Default | What it does |
|---|---|---|---|
profiles | array | โ | Profiles to scrape: handle, @handle or URL (up to 1,000) |
hashtags | array | โ | Hashtags to scrape: tag, #tag or URL (up to 100) |
resultsPerHashtag | integer | resultsPerPage | Videos per hashtag, from 10 to 10,000 |
resultsPerPage | integer | 100 | Videos per profile, from 10 to 10,000 (a profile with fewer returns all it has); with reposts, also the maximum reposts |
profileSorting | string | latest | Profiles: latest or oldest |
profileScrapeSections | array | ["videos"] | videos, reposts, or both |
commentsPerPost | integer | 0 | Comments included with each video (up to 1,000) |
maxRepliesPerComment | integer | 0 | Replies included under each comment (up to 1,000); a video carries at most 3,000 comments and replies in total |
oldestPostDateUnified | string | โ | Only videos published on or after this date |
newestPostDate | string | โ | Only videos published before this date |
selectedFields | array | every field (the form pre-selects the main ones) | Which columns to return (comments always come when requested) |
Field names match the ones used by the most used TikTok profile scraper, so a
profile-based input written for that Actor works here. Handles are not
case-sensitive, and profile URLs may carry extra parts such as ?lang=en.
At least one profile or hashtag is required.
Options this Actor does not offer (popular sorting, stories, search, post URLs, downloads, followers lists, likes and views filters) are
refused before anything is collected. The reason is in OUTPUT.
Pinned videos
Videos always come strictly by publish date. Pinned videos are ignored as
pinned: they never jump to the top of the list. A pinned video shows up at
its own date, like any other video. excludePinnedPosts is accepted.
Example input
{"profiles": ["nasa", "khaby.lame"],"resultsPerPage": 50,"profileSorting": "latest","commentsPerPost": 20}
A profile's first videos
{"profiles": ["zachking"],"resultsPerPage": 30,"profileSorting": "oldest"}
Oldest starts at the profile's very first video, and stays fast on large profiles.
Hashtags
{"hashtags": ["footballedit", "receitasfaceis"],"resultsPerHashtag": 100,"oldestPostDateUnified": "7 days"}
Videos come newest first, every one carrying the hashtag. Each item has
input (the hashtag) and searchHashtag (name, videoCount). The results
are the hashtag's recent public videos, not the full history of a hashtag with
millions of posts.
Filter by date
oldestPostDateUnified and newestPostDate take:
- a date:
2025-01-31 - an ISO timestamp:
2025-01-31T18:00:00Z(no time zone means UTC) - a relative period:
3 days,2 weeks,6 months,1 year(alsominutesandhours)
{"profiles": ["zachking"],"resultsPerPage": 1000,"oldestPostDateUnified": "2024-01-01","newestPostDate": "2025-01-01"}
That returns everything zachking published in 2024.
resultsPerPage counts only videos inside the dates. Videos outside them are
never delivered and never charged.
The date range applies to profile videos and hashtag videos. Reposts come in TikTok's order, newest reposts first, without a date filter.
Output
{"id": "7689510970292489502","webVideoUrl": "https://www.tiktok.com/@khaby.lame/video/7689510970292489502","text": "Yeโฆ Iโm gonna mind my business #learnfromkhaby #comedy","createTimeISO": "2026-09-25T16:30:18.000Z","playCount": 5700000,"diggCount": 690000,"commentCount": 15600,"shareCount": 39500,"collectCount": 33612,"hashtags": ["learnfromkhaby", "comedy"],"authorMeta": { "name": "khaby.lame", "nickName": "Khabane lame", "verified": true, "fans": 162966356, "heart": 2683467682, "video": 1356 },"musicMeta": { "musicName": "original sound", "musicAuthor": "Khabane lame", "musicOriginal": true, "duration": 26 },"videoMeta": { "duration": 26, "width": 720, "height": 1280, "definition": "720p", "format": "mp4" },"input": "khaby.lame","fromProfileSection": "videos","comments": [{"text": "KHABY LAME ๐ช๐ฟ","diggCount": 9890,"replyCount": 17,"authorUsername": "someone","replies": [{ "text": "Yooow", "diggCount": 16, "authorUsername": "someone.else" }]}]}
Above about 10,000, TikTok itself rounds video views and likes to 3 digits
(5,700,000), on its website too. Profile numbers in authorMeta are exact.
Every field
| Field | Type | What it is |
|---|---|---|
id | string | Video ID |
webVideoUrl | string | Link to the video |
text | string | Full caption |
textLanguage | string | Caption language |
createTime / createTimeISO | integer / string | Publish time, Unix seconds / ISO UTC |
playCount | integer | Views |
diggCount | integer | Likes |
commentCount | integer | Comments |
shareCount | integer | Shares |
collectCount | integer | Saves |
repostCount | integer | Reposts |
hashtags | array | Hashtags in the caption |
mentions | array | Handles mentioned in the caption |
detailedMentions | array | Mentioned profiles with ID and link |
isAd | boolean | Paid ad |
isSlideshow | boolean | Photo slideshow instead of a video |
slideshowImageLinks | array | Every photo of a slideshow |
location | object | Tagged place: name, address, city, country |
effectStickers | array | Effects used |
authorMeta | object | Profile (see above) |
musicMeta | object | Sound (see above) |
videoMeta | object | Video file details (see above) |
input | string | The profile or hashtag you asked for |
fromProfileSection | string | videos or reposts (profiles only) |
searchHashtag | object | Hashtag items only: name, videoCount |
comments | array | Comments: id, text, stickerUrl (sticker and GIF comments), diggCount, replyCount, createTimeISO, authorUsername, authorNickname, authorProfileUrl, likedByAuthor, pinnedByAuthor, language, and replies when requested (same fields, without replyCount) |
commentsIncomplete | boolean | Fewer comments than requested could be collected |
Cover and avatar links are temporary, as on TikTok itself: download them soon after the run. Video and audio files are not included.
You can download the dataset in JSON, CSV, Excel, HTML, XML or RSS.
API
Every run is available over the Apify API. Replace <TOKEN> with your API
token from Settings โ Integrations.
Run and wait for the results
curl -X POST "https://api.apify.com/v2/acts/<ACTOR_ID>/run-sync-get-dataset-items?token=<TOKEN>" \-H "Content-Type: application/json" \-d '{"profiles": ["nasa"],"resultsPerPage": 50}'
Best for small and medium jobs. The connection stays open until the run ends, so keep a generous client timeout.
Python
from apify_client import ApifyClientclient = ApifyClient("<TOKEN>")run = client.actor("<ACTOR_ID>").call(run_input={"profiles": ["nasa"],"resultsPerPage": 100,"commentsPerPost": 20,})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["webVideoUrl"], item["playCount"], len(item.get("comments", [])))
JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<TOKEN>' });const run = await client.actor('<ACTOR_ID>').call({profiles: ['nasa'],resultsPerPage: 100,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items.length);
Run summary
Besides the dataset, each run writes an OUTPUT record to the key-value store
with a summary per profile and per hashtag:
{"ok": true,"total_items": 150,"total_comments": 2400,"profiles": [{ "profile": "nasa", "count": 100, "comments": 1600 },{ "profile": "khaby.lame", "count": 50, "comments": 800 },{ "hashtag": "footballedit", "count": 100 }]}
With reposts, each profile also has sections (videos and reposts counted
apart). A profile can carry notes, for example
reposts could not be collected right now, please try again later or
no reposts found. The summary has timed_out: true when the run reached its
time limit and charge_limit_reached: true when it reached the maximum cost
you set.
When a profile cannot be completed, its entry carries an error field and the
videos already collected stay in the dataset. The error is one of:
error | What it means | What to do |
|---|---|---|
profile not found or unavailable | The handle does not exist, was renamed or banned | Check the handle |
profile is private | The profile is private | Nothing: only public profiles can be read |
no public videos found | The profile has no public videos | Check the profile |
no videos published in the requested date range | Nothing inside your dates | Widen the range |
could not be collected right now, please try again later | A temporary problem on TikTok's side | Run that profile again later |
collection stopped early, please try again later for the rest | Some videos were collected, then a temporary problem stopped it | Run again later for the rest |
the run time limit was reached before this profile finished; videos collected so far are in the dataset | The run's timeout arrived mid-profile | Give the run a longer timeout |
not started: run time limit reached | The timeout arrived before this profile's turn | Give the run a longer timeout |
not started: the maximum cost set for this run was reached | The run reached the maximum cost you set | Raise it, or run the rest separately |
not started: TikTok is refusing requests right now, please try again later | TikTok refused several profiles in a row | Run again later |
not a valid TikTok profile | The entry is not a handle or profile URL | Fix the entry |
hashtag not found | The hashtag does not exist | Check the hashtag |
not a valid hashtag | The entry has spaces or invalid characters | Fix the entry |
Sizing the timeout. Without comments, a run collects several hundred videos per minute. With 50 comments per video, 100 videos take about 2 minutes. When the timeout is close, the run stops on its own, writes this summary and finishes as Succeeded, keeping everything collected so far.
What people use this for
- Daily tracking of views, likes, comments, shares and saves per video.
- Influencer vetting: reach versus engagement over the last videos.
- Content research: which videos, hashtags and sounds perform.
- Comment analysis: what the audience says, with replies.
- Hashtag monitoring: the newest videos of a hashtag, every day.
- Period reports for a month, quarter or campaign.
Frequently asked questions
Can I get the comment text?
Yes. Set commentsPerPost, and maxRepliesPerComment for the replies. They
come inside each video, most relevant first. Comments that are only a sticker
or GIF come with stickerUrl.
Why are some views rounded? TikTok publishes video views and likes rounded to 3 digits above about 10,000, on its own website too. That is the number TikTok gives out. Profile numbers (followers, total likes) are exact.
Can I choose which columns I get?
Yes. Pick them in Fields to return (selectedFields). Leave it empty and
you get every field. Comments are always included when you ask for them.
Can I sort by most viewed?
No. Videos come by publish date. Pull the period you care about and sort by
playCount in your spreadsheet.
Why is an old pinned video not at the top? Pinned videos are ignored as pinned. The list is always by publish date, so "Latest" really is the latest, and each pinned video appears at its own date.
How many videos can I get from a hashtag?
Up to resultsPerHashtag, newest first. Large hashtags usually return a few
hundred recent videos per run; a smaller hashtag can return fewer than you ask
for.
Can I scrape private profiles?
No. Only public profiles return data. A private profile is skipped and marked
in OUTPUT, and the rest of the run continues.
What happens if one profile fails?
The other profiles keep going. Videos already collected stay in the dataset,
and the OUTPUT record marks that profile with an error field.
Can I ask for more videos than the profile has? Yes. You get everything available and the run ends normally.
Do I need a proxy or a login? No. There is nothing to configure: no cookies, no session, no browser.
What are reposts?
Videos from other accounts that the profile reposted. authorMeta is the
original author, and input is the profile that reposted it.
How much does it cost?
| Free plan | Any paid Apify plan | |
|---|---|---|
| Videos | $0.10 per 1,000 | $0.05 per 1,000 |
| Comments and replies | $0.05 per 1,000 | $0.025 per 1,000 |
Charged per video and per comment delivered: each reply counts as one comment.
A run that returns nothing costs nothing. If you set a maximum cost for a run,
the run stops when it is reached, keeps everything collected so far, and says
so in its status and in OUTPUT (charge_limit_reached).
How do I track a profile every day?
Create a task with your profiles and schedule it daily in Apify. Each run is a
snapshot of that day: join the runs by video id to see how playCount,
diggCount, commentCount, shareCount and collectCount evolve, and by
authorMeta.name to follow fans and heart. To pick up only new videos, set
oldestPostDateUnified to 1 day.
Is this affiliated with TikTok? No. See the disclaimer at the bottom.
Notes and limits
- Only public profiles are supported.
- A profile that is unavailable is skipped with a warning; the other profiles in the same run continue normally.
- Requesting more videos than a profile has simply returns everything available.
Support
Found a bug or need a field that is not on the list? Open an issue on the Actor's Issues tab with the input you used and the run ID.
Disclaimer
This is an unofficial tool and is not affiliated with, endorsed by, or sponsored by TikTok or ByteDance Ltd. It collects only publicly available content. You are responsible for how you use the data, including compliance with applicable laws and the target site's terms.