TikTok Data Scraper (Hashtag, Sound & Playlist Analytics) avatar

TikTok Data Scraper (Hashtag, Sound & Playlist Analytics)

Pricing

from $5.99 / 1,000 results

Go to Apify Store
TikTok Data Scraper (Hashtag, Sound & Playlist Analytics)

TikTok Data Scraper (Hashtag, Sound & Playlist Analytics)

๐ŸŽฌ TikTok Data Scraper extracts creator & video analytics from TikTokโ€”captions, hashtags, views, likes, comments, and more. ๐Ÿš€ Boost B2B research, competitive insights & content strategy with faster, cleaner data collection. ๐Ÿ“ˆโœจ

Pricing

from $5.99 / 1,000 results

Rating

0.0

(0)

Developer

Scrapier

Scrapier

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Share

TikTok Hashtag Scraper โ€” Sound, Playlist & Trend Analytics

TikTok Hashtag Scraper โ€” Sound, Playlist & Trend Analytics pulls public TikTok videos for any hashtag, sound, or playlist in one run, then computes engagement rate, view velocity, comment-to-view ratio, and duration bucket for every video before it's saved. Loop a hashtag across several regions in the same job, or use the profile, comment, and single-video lookup modes inherited from the base TikTok Data Scraper. Every response is structured JSON โ€” ready to pass directly to an LLM, index into a vector store, or feed a monitoring pipeline for TikTok trend tracking.


๐Ÿ“– What is the TikTok Data Scraper (Hashtag, Sound & Playlist Analytics)?

It's a TikTok data extraction Actor built around one unified trend batch: give it hashtags, sounds, and/or playlists and it collects every video across all of them in a single run, tags each with its source (sourceFacet), and computes engagement analytics on the fly โ€” the part a plain hashtag scraper or post lister leaves for you to calculate in a spreadsheet. It keeps every feature of the base TikTok Data Scraper too: user videos, favourites, followers, following, in-profile search, profile info, video comments/replies, and single-video detail lookups.

No TikTok account, login, or cookies are required โ€” every category returns only what a logged-out visitor can already see on tiktok.com.

  • #๏ธโƒฃ Unified hashtag + sound + playlist trend batch โ€” mix trendHashtags, trendSounds, and trendPlaylists in one run; every saved video carries sourceFacet (hashtag / sound / playlist).
  • ๐ŸŒ Multi-region hashtag looping โ€” list several 2-letter codes in trendHashtagRegions and each hashtag is fetched once per region, in the same job.
  • ๐Ÿงฎ Derived trend analytics โ€” engagementRate, viewVelocity, commentToViewRatio, and durationBucket computed locally on every trend-batch video, no extra requests spent.
  • ๐Ÿšซ Tier-1 filters โ€” minDiggCount, minPlayCount, oldestDate, and excludeKeywords drop low-value videos before they're saved (and before they're charged).
  • ๐Ÿ‘ค Full profile toolkit โ€” videos, favourite videos, following, followers, in-profile search, and profile info via userUrls + categories.
  • ๐Ÿ’ฌ Comments and replies โ€” videoUrlsComments pulls comments and, with repliesPerComment, nested replies for any video.

๐Ÿ“Š What data can you get with this TikTok trend scraper?

Every result type below is available in the same run and lands in the dataset as JSON.

Result TypeExtracted FieldsPrimary Use Case
Hashtag trend videosvideo_id, title, play_count, digg_count, comment_count, share_count, engagementRate, viewVelocity, commentToViewRatio, durationBucket, hashtagUrl, videoUrlRanking hashtag trends by engagement, not just raw view count
Sound / music trend videosSame video fields, plus music_info, musicUrlSpotting which creators are riding a trending sound right now
Playlist (mix) trend videosSame video fields, sourceFacet = "playlist"Tracking curated playlist performance over time
User videos / favourites / search resultsvideo_id, author.nickname, author.unique_id, play_count, digg_count, duration, videoUrl, profileUrlProfile-level content audits
Following / followersRaw profile-card fields returned by the data sourceAudience and network mapping
User infounique_id, nickname, signature, bioLink, ins_id, twitter_id, youtube_channel_id, stats, avatarCreator profile enrichment
Comments & repliesid, text, digg_count, reply_total, user.nickname, user.unique_id, user.follower_count, isReply, reply_to_comment_idSentiment and community analysis
Single video detailsFull video record (HD link, stats, author, music)Deep-diving on one specific video

Derived trend analytics

Every trend-batch video (hashtag, sound, or playlist facet) gets four extra fields computed locally from the counters TikTok already returns โ€” no AI, no extra API calls. engagementRate is (digg_count + comment_count + share_count + collect_count) / play_count, only computed when plays are known (never faked as 0). viewVelocity is plays divided by hours since create_time, so a video that's 30 minutes old is compared fairly against one that's 3 days old. commentToViewRatio flags videos generating outsized discussion relative to their reach. durationBucket sorts each video into short (<15s), medium (15โ€“60s), or long (>60s) so you can compare formats fairly.

{
"engagementRate": 0.19811,
"viewVelocity": 5321.4,
"commentToViewRatio": 0.00252,
"durationBucket": "medium"
}

Comments & replies

Comments come back flat, one record per comment, with isReply: false. When repliesPerComment is greater than 0 (or scrapeAllReplies is on) and a comment's reply_total is above 0, its replies are fetched separately and emitted as their own records with isReply: true and reply_to_comment_id pointing back at the parent โ€” useful for reconstructing full comment threads or measuring which comments actually spark conversation.


๐Ÿ› ๏ธ Why not build this yourself?

TikTok has no public search or trend API that covers hashtags, sounds, and playlists together with engagement analytics โ€” building this from scratch means maintaining your own scraper against a query surface that changes without notice. In practice this Actor already hit exactly that problem: the underlying data source's videos and favourite_videos routes sit behind a genuine, persistent Cloudflare interactive challenge that a fresh IP does not clear โ€” confirmed across direct, datacenter, and residential proxy tiers, multiple session strategies, and a real headless browser. Handling that correctly means detecting the specific challenge signature (rather than retrying forever), escalating through a proxy ladder, and โ€” for the videos category only โ€” falling back to a slower, browser-based route straight to tiktok.com that isn't guaranteed to succeed on the first attempt.

None of that is a one-time build. It's an ongoing maintenance cost: proxy budget, retry tuning, and re-verifying the block signature every time TikTok's anti-bot layer changes. This Actor absorbs that cost and exposes the result as a handful of input fields โ€” you supply hashtags, sounds, and playlists; it handles the escalation ladder and the fallback route behind the scenes.


๐Ÿ” What is the difference between a TikTok hashtag scraper and TikTok trend analytics?

A plain TikTok hashtag scraper returns a list of videos under a hashtag โ€” title, view count, like count, and not much else. TikTok trend analytics goes a step further: it takes that same video data and computes comparable metrics across videos of different ages and formats, so you can rank them instead of just listing them.

The distinction matters because raw counts are misleading on their own. A video with 1 million views posted three days ago is not "more viral" than one with 200,000 views posted two hours ago โ€” viewVelocity (plays per hour since publish) makes that comparison fair. Likewise, play_count alone hides how much of an audience actually engaged; engagementRate and commentToViewRatio surface that.

This Actor returns both in the same JSON object: the raw hashtag/sound/playlist video list (data.play_count, data.digg_count, data.comment_count, data.share_count) and the derived analytics (data.engagementRate, data.viewVelocity, data.commentToViewRatio, data.durationBucket) computed on top of it โ€” so you don't need a second tool or a spreadsheet formula to move from "here's a list" to "here's what's actually trending."


๐Ÿš€ How to scrape TikTok with this Actor

  1. Open the Actor on its Apify Store listing and click Try for free (or Start if you've already added it to your account).
  2. Add your query under the relevant input section โ€” hashtag names/URLs in trendHashtags, sound URLs/IDs in trendSounds, playlist (mix) IDs in trendPlaylists, or a profile in userUrls.
  3. Set the real query controls that apply: trendHashtagRegions for multi-region looping, videosPerHashtag / videosPerMusic / videosPerPlaylist (or the matching scrapeAll* toggle) for volume, and the Tier-1 filters (minDiggCount, minPlayCount, oldestDate, excludeKeywords) to narrow the batch.
  4. Click Start.
  5. Watch the live log for per-region, per-facet progress, then open the Output tab to view results in the ready-made table views or export as JSON / CSV.
{
"trendHashtags": ["dance", "aiart"],
"trendHashtagRegions": ["US", "GB"],
"videosPerHashtag": 40,
"minDiggCount": 1000
}

How to run multiple queries in one job

Every array-type input โ€” trendHashtags, trendSounds, trendPlaylists, userUrls, videoUrlsComments, videoDetailsList โ€” accepts a list, so one run can cover many hashtags, sounds, playlists, and profiles together as a single trend batch. Region looping multiplies inside that same run: each hashtag is fetched once per entry in trendHashtagRegions, so 3 hashtags across 3 regions produce 9 hashtag/region combinations, each drawing up to videosPerHashtag videos. The source code processes queued sources through a single worker rather than in parallel, so total run time scales with the number of sources and the per-source limits you set, not just the item count of any one hashtag.


โฌ‡๏ธ Input

Fill in only the section(s) you need โ€” every field is optional (required: [] in the schema) and unused sections can stay empty.

ParameterRequiredTypeDescriptionExample Value
userUrlsNoarrayProfile URLs, @handles, plain usernames, or numeric user IDs.["https://www.tiktok.com/@taylorswift"]
categoriesNoarrayWhich user data to collect per profile: videos, favourite_videos, followers, following, search, user_info. Default ["videos"].["videos", "user_info"]
maxUserResultsNointegerMax items per profile/section. Minimum 1, default 10. Ignored when scrapeAllUserResults is on.40
scrapeAllUserResultsNobooleanIgnore maxUserResults and collect everything available. Default false.false
videoUrlsCommentsNoarrayVideo URLs or IDs to scrape comments from.["https://www.tiktok.com/@user/video/7123456789"]
commentsPerUrlNointegerMax comments per video. Minimum 1, default 10. Ignored when scrapeAllComments is on.50
scrapeAllCommentsNobooleanCollect every available comment per video. Default false.false
repliesPerCommentNointegerMax replies per comment. Minimum 0, default 0 (replies skipped). Ignored when scrapeAllReplies is on.10
scrapeAllRepliesNobooleanCollect every available reply for each comment. Default false.false
trendHashtagsNoarrayHashtag names or URLs for the trend batch.["dance", "aiart"]
trendHashtagRegionsNoarray2-letter region codes; each hashtag loops across every region listed. Also accepts the legacy single hashtagRegion. Leave empty for US only.["US", "GB", "IN"]
videosPerHashtagNointegerMax videos per hashtag, per region. Minimum 1, default 10. Ignored when scrapeAllHashtagVideos is on.40
scrapeAllHashtagVideosNobooleanCollect every available video per hashtag/region combination. Default false.false
trendSoundsNoarraySound/music URLs or IDs for the trend batch. Also accepts the legacy musicUrls.["https://www.tiktok.com/music/original-sound-123456789"]
videosPerMusicNointegerMax videos per sound. Minimum 1, default 10. Ignored when scrapeAllMusicVideos is on.40
scrapeAllMusicVideosNobooleanCollect every available video per sound. Default false.false
trendPlaylistsNoarrayPlaylist (mix) IDs for the trend batch. Also accepts the legacy playlistIDs.["7123456789012345678"]
videosPerPlaylistNointegerMax videos per playlist. Minimum 1, default 10. Ignored when scrapeAllPlaylistVideos is on.40
scrapeAllPlaylistVideosNobooleanCollect every available video per playlist. Default false.false
minDiggCountNointegerSkip trend-batch videos with fewer likes than this. Minimum 0, default 0 (no minimum).1000
minPlayCountNointegerSkip trend-batch videos with fewer plays than this. Minimum 0, default 0 (no minimum).5000
oldestDateNostringSkip trend-batch videos published before this date. Absolute (YYYY-MM-DD) or relative ("7 days", "1 month"). Leave empty to disable."7 days"
excludeKeywordsNoarraySkip trend-batch videos whose title/description contains any of these keywords (case-insensitive).["ad", "sponsored"]
videoDetailsListNoarrayVideo IDs or URLs to retrieve full detail records for.["7123456789012345678"]
hashtagsNoarray(Legacy) same as trendHashtags. Used only when trendHashtags is empty.["dance"]
hashtagRegionNostring(Legacy) same as trendHashtagRegions (single value). Used only when trendHashtagRegions is empty. Pattern: two letters."US"
musicUrlsNoarray(Legacy) same as trendSounds. Used only when trendSounds is empty.[]
playlistIDsNoarray(Legacy) same as trendPlaylists. Used only when trendPlaylists is empty.[]
minRequestIntervalNonumberSeconds between consecutive requests. Minimum 0, maximum 10, default 1.2. Lower is faster but more likely to be rate-limited.1.2
maxRetriesNointegerHow many times to retry a failed/blocked request before giving up. Minimum 0, maximum 10, default 3.3
apiKeyNostringOptional key that lifts the upstream rate limit. Default "" (free tier).""
proxyConfigurationNoobjectProxy settings. Default {"useApifyProxy": false} โ€” no proxy, with automatic escalation to datacenter then residential on a block.{"useApifyProxy": false}
{
"trendHashtags": ["dance", "aiart"],
"trendHashtagRegions": ["US", "GB"],
"videosPerHashtag": 40,
"trendSounds": [],
"trendPlaylists": [],
"minDiggCount": 1000,
"minPlayCount": 5000,
"oldestDate": "7 days",
"excludeKeywords": ["ad", "sponsored"],
"userUrls": [],
"videoUrlsComments": [],
"videoDetailsList": [],
"minRequestInterval": 1.2,
"maxRetries": 3,
"proxyConfiguration": { "useApifyProxy": false }
}

Common pitfall: the legacy fields (hashtags, musicUrls, playlistIDs, hashtagRegion) are only read when their new counterpart (trendHashtags, trendSounds, trendPlaylists, trendHashtagRegions) is completely empty โ€” populating both in the same run silently ignores the legacy field, it does not merge the two lists.

โš ๏ธ Known limitation: the videos and favourite_videos categories depend on a route that is sometimes behind a persistent Cloudflare challenge on the upstream data source. When that happens, videos automatically retries through a slower browser-based fallback straight to tiktok.com (capped at 200 videos per profile, not guaranteed to succeed on every attempt), while favourite_videos has no equivalent fallback and returns 0 items for that run with a clear log warning. Every other category is unaffected.


โฌ†๏ธ Output

Every record is pushed to the dataset live, the moment it's collected, so a stopped or crashed run keeps whatever it already saved. Every record shares the same top-level envelope; the data object's shape depends on category โ€” video records follow a fixed field order plus any extra field the upstream API adds (for example hdplay, an HD no-watermark link, which isn't in the fixed field list but is still carried through untouched), while user, comment, and follower records mirror the source API's own object shape. Results can be exported from the Output tab as JSON, CSV, Excel, HTML, or RSS.

Scraped results

[
{
"section": "hashtags",
"category": "videos",
"sourceFacet": "hashtag",
"region": "US",
"input": "dance",
"user": "dance",
"userType": "hashtag",
"publishedAt": "2026-07-28T14:03:21Z",
"scrapedAt": "2026-08-04T10:12:05Z",
"data": {
"video_id": "7647758735229635871",
"title": "โ€ฆ",
"duration": 25,
"play_count": 13686605,
"digg_count": 2579867,
"comment_count": 34525,
"share_count": 115161,
"engagementRate": 0.19811,
"viewVelocity": 5321.4,
"commentToViewRatio": 0.00252,
"durationBucket": "medium",
"videoUrl": "https://www.tiktok.com/@taylorswift/video/7647758735229635871",
"hashtagUrl": "https://www.tiktok.com/hashtag/dance",
"musicUrl": "https://www.tiktok.com/music/original-sound-123456789",
"profileUrl": "https://www.tiktok.com/@taylorswift",
"author": { "id": "โ€ฆ", "unique_id": "taylorswift", "nickname": "Taylor Swift" }
}
},
{
"section": "videos",
"category": "comments",
"input": "7123456789012345678",
"user": "7123456789012345678",
"userType": "video_id",
"publishedAt": "2026-07-30T09:11:00Z",
"scrapedAt": "2026-08-04T10:14:02Z",
"data": {
"id": "7647999999999999999",
"text": "this is everything",
"digg_count": 412,
"reply_total": 3,
"isReply": false,
"user": { "nickname": "fan_account", "unique_id": "fan_account", "follower_count": 890 }
}
},
{
"section": "users",
"category": "user_info",
"input": "taylorswift",
"user": "taylorswift",
"userType": "unique_id",
"publishedAt": null,
"scrapedAt": "2026-08-04T10:15:40Z",
"data": {
"unique_id": "taylorswift",
"nickname": "Taylor Swift",
"signature": "โ€ฆ",
"bioLink": "โ€ฆ",
"avatar": "https://โ€ฆ",
"stats": { "followerCount": 123456789, "videoCount": 512 },
"profileUrl": "https://www.tiktok.com/@taylorswift"
}
}
]

Each row is billed once it's saved, as a result-item charge on the row_result event. No error or accounting rows are ever pushed to the dataset โ€” failures are only written to the run log, so nothing in your dataset needs to be filtered out as an uncharged placeholder row. If a run reaches its configured charge limit, collection and saving continue but new charges stop, and the log states this explicitly.


๐Ÿ’ก How can I use the data extracted with this Actor?

  • ๐Ÿ“Š Social media managers and brand strategists: track which hashtags and sounds are worth a brand's next campaign by ranking engagementRate and viewVelocity across a watchlist instead of eyeballing raw view counts.
  • ๐Ÿค– AI engineers and LLM developers: an agent issues a query โ€” a hashtag, sound, or playlist โ€” receives structured JSON with pre-computed trend metrics, and passes it straight to the model as grounded context for a trend-summary or content-brief tool.
  • ๐Ÿ”ฌ Market researchers: measure share-of-voice for a topic across regions using trendHashtagRegions, and track volatility over time by re-running the same hashtag set on a schedule.
  • ๐ŸŽฏ Talent scouts and content teams: use trendSounds to spot which creators are riding a sound early, before it saturates, using viewVelocity as the leading signal.

๐Ÿ“ˆ How do you monitor TikTok trend performance over time?

Trend monitoring means running the same hashtag, sound, or playlist set repeatedly and comparing the results, not scraping once and stopping. Between two runs on the same trendHashtags/trendSounds/trendPlaylists input, diff play_count, digg_count, comment_count, and the derived engagementRate and viewVelocity for videos that appear in both runs (matched by video_id), and watch for new video_id values entering the top of the list, which signals a fresh video catching momentum on that hashtag or sound.

A practical loop: schedule a run across your watchlist of hashtags/sounds/playlists using Apify's Console Schedule feature (e.g. every few hours), export or fetch each run's dataset, and alert when a video's viewVelocity jumps sharply between two consecutive runs โ€” that's the earliest signal a video is starting to break out, well before raw play_count alone would show it. Pair this with the Tier-1 filters (minDiggCount, minPlayCount, oldestDate) so the watchlist only ever contains videos already worth tracking, keeping the comparison set stable and low-noise across scheduled runs.


๐Ÿ”Œ Integrate this Actor and automate your workflow

This Actor works with any language or tool that can send an HTTP request or use the Apify SDK.

REST API with Python

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run_input = {
"trendHashtags": ["dance"],
"trendHashtagRegions": ["US", "GB"],
"minDiggCount": 1000,
"videosPerHashtag": 40,
}
run = client.actor("<store-username>/tiktok-data-scraper-hashtag-sound-and-playlist-analytics").call(
run_input=run_input
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item["data"].get("engagementRate"), item["data"].get("videoUrl"))

Scheduled monitoring and delivery

Apify's Console lets you attach a Schedule to this Actor to re-run the same input on a recurring basis, and attach a webhook to a run's completion event to push a notification (or trigger a downstream job) as soon as a scheduled run finishes โ€” this Actor does not need any code changes to use either; both are configured directly against the Actor in the Apify Console.


Yes โ€” scraping publicly accessible TikTok data is generally legal; this Actor returns only what any logged-out visitor to tiktok.com can already see, without logging in or bypassing any access control.

Because the output includes personal data โ€” creator and commenter usernames, nicknames, bios, avatars, linked social handles, and follower counts, alongside video content โ€” GDPR (if you or your data subjects are in the EU/UK) and CCPA (for California residents) can attach to how you store and process it, separately from whether the initial collection was lawful. TikTok's own Terms of Service govern what you may do with the platform itself, independent of data protection law. Scraping for one-off operational monitoring carries a different risk profile than scraping for AI training or bulk long-term storage of personal data. Consult your legal team for commercial use cases involving bulk data storage or processing of personal data.


โ“ Frequently asked questions

Can I track the same hashtag across multiple countries?

Yes โ€” list multiple 2-letter codes in trendHashtagRegions (for example ["US", "GB", "IN"]) and each hashtag in trendHashtags is fetched once per region in the same run, with the region tagged on every saved record.

Can I control which user data categories are scraped?

Yes โ€” categories is a multi-select array accepting videos, favourite_videos, followers, following, search, and user_info; only the categories you list are collected for each profile in userUrls.

How does this Actor handle TikTok's anti-bot measures?

It starts on a direct connection, paces requests with a configurable minimum interval (minRequestInterval, default 1.2s) and retry budget (maxRetries, default 3), and automatically escalates through a datacenter-then-residential proxy ladder on a block, sticking with residential once engaged. For the videos category specifically, if the upstream route hits a persistent Cloudflare challenge, it falls back to a slower browser-based route directly against tiktok.com.

Does this Actor calculate engagement rate and trend velocity?

Yes โ€” every trend-batch video (hashtag, sound, or playlist facet) includes engagementRate, viewVelocity, commentToViewRatio, and durationBucket in its data object, computed locally from the counters TikTok already returns. engagementRate and commentToViewRatio are null when play_count is 0 or unavailable, rather than a faked zero.

How many results does this Actor return per query?

Each category defaults to 10 items (maxUserResults, commentsPerUrl, videosPerHashtag, videosPerMusic, videosPerPlaylist all default to 10; repliesPerComment defaults to 0). Set the matching scrapeAll* toggle to collect everything available instead of a fixed count. The one hard ceiling: the browser-based fallback used when the videos category hits a Cloudflare block caps collection at 200 videos per profile regardless of what you requested.

Why does the followers category sometimes return 0 results?

TikTok's public followers-list data is currently unavailable through this Actor's data source specifically โ€” it returns 0 results with a clear warning in the log rather than failing silently or guessing. following, videos, comments, and every other category are unaffected.

Is this Actor compatible with the original TikTok Data Scraper's input format?

Yes โ€” hashtags, musicUrls, playlistIDs, and hashtagRegion are accepted as legacy aliases and are used whenever their new counterpart (trendHashtags, trendSounds, trendPlaylists, trendHashtagRegions) is left empty.

How do I use this Actor to monitor a hashtag's performance over time?

Schedule a recurring run on the same trendHashtags/trendSounds/trendPlaylists set via Apify's Console Schedule feature, then diff play_count, digg_count, engagementRate, and viewVelocity for matching video_ids between runs, and watch for new video_ids entering the results as the signal a new video is picking up momentum.

Does this Actor work with Claude, ChatGPT, and AI agent frameworks?

It's callable as an HTTP endpoint (via the Apify API or apify_client) by any agent framework that can make a request โ€” an agent can issue a hashtag/sound/playlist query, receive the structured JSON response including the derived trend metrics, and generate a grounded, up-to-date answer from it.

Can I use this Actor without managing my own proxies or a TikTok account?

Yes โ€” it runs on a direct connection by default and only reaches for Apify's datacenter and residential proxies automatically if TikTok blocks the direct route; you don't need to supply your own proxy pool. No TikTok login or account is required for any category.


๐Ÿ’ฌ Your feedback

Found a bug or missing a field? Open an issue on the Actor's Issues tab in the Apify Console โ€” feedback is welcome and shapes what gets built next.