TikTok Scraper - from $0.05 per 1,000 videos avatar

TikTok Scraper - from $0.05 per 1,000 videos

Pricing

from $0.05 / 1,000 videos

Go to Apify Store
TikTok Scraper - from $0.05 per 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

Esdrasdw

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

10 hours ago

Last modified

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

  1. In the Profiles block, add profiles: a handle (nasa), @nasa or a profile URL (https://www.tiktok.com/@nasa). Set Videos per profile and pick Sort videos by: Latest or Oldest.
  2. In the Hashtags block, add hashtags: fyp, #fyp or https://www.tiktok.com/tag/fyp, and set Videos per hashtag. Fill in profiles, hashtags or both.
  3. Optionally, add Reposts under Profile sections.
  4. Optionally, set Comments per video and Replies per comment.
  5. Optionally, narrow it down under Date range.
  6. Optionally, pick the columns under Fields to return.
  7. Run it, then download the dataset as JSON, CSV, Excel or HTML.

Input

FieldTypeDefaultWhat it does
profilesarrayโ€”Profiles to scrape: handle, @handle or URL (up to 1,000)
hashtagsarrayโ€”Hashtags to scrape: tag, #tag or URL (up to 100)
resultsPerHashtagintegerresultsPerPageVideos per hashtag, from 10 to 10,000
resultsPerPageinteger100Videos per profile, from 10 to 10,000 (a profile with fewer returns all it has); with reposts, also the maximum reposts
profileSortingstringlatestProfiles: latest or oldest
profileScrapeSectionsarray["videos"]videos, reposts, or both
commentsPerPostinteger0Comments included with each video (up to 1,000)
maxRepliesPerCommentinteger0Replies included under each comment (up to 1,000); a video carries at most 3,000 comments and replies in total
oldestPostDateUnifiedstringโ€”Only videos published on or after this date
newestPostDatestringโ€”Only videos published before this date
selectedFieldsarrayevery 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 (also minutes and hours)
{
"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

FieldTypeWhat it is
idstringVideo ID
webVideoUrlstringLink to the video
textstringFull caption
textLanguagestringCaption language
createTime / createTimeISOinteger / stringPublish time, Unix seconds / ISO UTC
playCountintegerViews
diggCountintegerLikes
commentCountintegerComments
shareCountintegerShares
collectCountintegerSaves
repostCountintegerReposts
hashtagsarrayHashtags in the caption
mentionsarrayHandles mentioned in the caption
detailedMentionsarrayMentioned profiles with ID and link
isAdbooleanPaid ad
isSlideshowbooleanPhoto slideshow instead of a video
slideshowImageLinksarrayEvery photo of a slideshow
locationobjectTagged place: name, address, city, country
effectStickersarrayEffects used
authorMetaobjectProfile (see above)
musicMetaobjectSound (see above)
videoMetaobjectVideo file details (see above)
inputstringThe profile or hashtag you asked for
fromProfileSectionstringvideos or reposts (profiles only)
searchHashtagobjectHashtag items only: name, videoCount
commentsarrayComments: id, text, stickerUrl (sticker and GIF comments), diggCount, replyCount, createTimeISO, authorUsername, authorNickname, authorProfileUrl, likedByAuthor, pinnedByAuthor, language, and replies when requested (same fields, without replyCount)
commentsIncompletebooleanFewer 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 ApifyClient
client = 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:

errorWhat it meansWhat to do
profile not found or unavailableThe handle does not exist, was renamed or bannedCheck the handle
profile is privateThe profile is privateNothing: only public profiles can be read
no public videos foundThe profile has no public videosCheck the profile
no videos published in the requested date rangeNothing inside your datesWiden the range
could not be collected right now, please try again laterA temporary problem on TikTok's sideRun that profile again later
collection stopped early, please try again later for the restSome videos were collected, then a temporary problem stopped itRun again later for the rest
the run time limit was reached before this profile finished; videos collected so far are in the datasetThe run's timeout arrived mid-profileGive the run a longer timeout
not started: run time limit reachedThe timeout arrived before this profile's turnGive the run a longer timeout
not started: the maximum cost set for this run was reachedThe run reached the maximum cost you setRaise it, or run the rest separately
not started: TikTok is refusing requests right now, please try again laterTikTok refused several profiles in a rowRun again later
not a valid TikTok profileThe entry is not a handle or profile URLFix the entry
hashtag not foundThe hashtag does not existCheck the hashtag
not a valid hashtagThe entry has spaces or invalid charactersFix 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 planAny 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.