How to Scrape TikTok Creator Profiles and Video Stats Without the API
TikTok's official API requires approval and heavily rate-limits what you can access. For follower counts, video views, engagement rates, and trending content at scale — you need to scrape it.
Here's what works in 2026.
What TikTok Actually Lets You Extract (Without API)
| Data Point | Available |
|---|---|
| Username, display name, bio | ✅ |
| Follower/following/likes count | ✅ |
| Video titles, hashtags, descriptions | ✅ |
| View counts, likes, comments, shares | ✅ |
| Video URLs and thumbnails | ✅ |
| Music/audio info | ✅ |
| Creator verification status | ✅ |
| Posting frequency | ✅ (from timestamps) |
Method 1: TikTok's Internal API (Python)
TikTok loads most data via an internal API that you can hit directly with the right headers:
import requests
import json
def scrape_tiktok_profile(username):
"""Fetch TikTok profile data via internal API."""
# TikTok's web API endpoint
url = "https://www.tiktok.com/api/user/detail/"
params = {
"uniqueId": username,
"msToken": "", # Not required for basic profile data
"aid": "1988",
"app_name": "tiktok_web",
}
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Referer": f"https://www.tiktok.com/@{username}",
"Accept": "application/json",
}
r = requests.get(url, params=params, headers=headers, timeout=15)
if r.status_code != 200:
print(f"Error: {r.status_code}")
return None
data = r.json()
user = data.get("userInfo", {}).get("user", {})
stats = data.get("userInfo", {}).get("stats", {})
return {
"username": user.get("uniqueId"),
"nickname": user.get("nickname"),
"bio": user.get("signature"),
"follower_count": stats.get("followerCount"),
"following_count": stats.get("followingCount"),
"video_count": stats.get("videoCount"),
"total_likes": stats.get("heartCount"),
"is_verified": user.get("verified", False),
}
profile = scrape_tiktok_profile("charlidamelio")
print(json.dumps(profile, indent=2))
Note: TikTok's WAF updates frequently. For production use, add proxy rotation and handle 403s.
Method 2: Playwright for Video Data
Getting individual video stats requires JavaScript execution:
from playwright.sync_api import sync_playwright
import json, re, time
def get_tiktok_videos(username, max_videos=20):
"""Scrape video stats from a TikTok profile."""
videos = []
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
context = browser.new_context(
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124.0.0.0"
)
# Capture API responses
def handle_response(response):
if "item_list" in response.url:
try:
data = response.json()
items = data.get("itemList", [])
for item in items:
stats = item.get("stats", {})
videos.append({
"video_id": item.get("id"),
"description": item.get("desc", ""),
"views": stats.get("playCount", 0),
"likes": stats.get("diggCount", 0),
"comments": stats.get("commentCount", 0),
"shares": stats.get("shareCount", 0),
"hashtags": [h.get("hashtagName") for h in item.get("challenges", [])],
})
except:
pass
page = context.new_page()
page.on("response", handle_response)
page.goto(f"https://www.tiktok.com/@{username}")
time.sleep(3)
# Scroll to trigger more video loads
for _ in range(5):
page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
time.sleep(1.5)
browser.close()
return videos[:max_videos]
videos = get_tiktok_videos("charlidamelio")
for v in videos[:3]:
print(f"Views: {v['views']:,} | Likes: {v['likes']:,} | {v['description'][:60]}")
Method 3: Apify Actor (Scales Without Headaches)
Managing TikTok session rotation and bot fingerprinting at scale is complex. The TikTok Profile Scraper on Apify handles this automatically.
import requests, time
run = requests.post(
"https://api.apify.com/v2/acts/lanky_quantifier~tiktok-profile-scraper/runs",
headers={"Authorization": "Bearer YOUR_APIFY_TOKEN"},
json={
"usernames": ["charlidamelio", "khaby.lame", "bellapoarch"],
"maxVideosPerProfile": 30,
"includeVideoStats": True
}
).json()["data"]
while True:
status = requests.get(
f"https://api.apify.com/v2/actor-runs/{run['id']}",
headers={"Authorization": "Bearer YOUR_APIFY_TOKEN"}
).json()["data"]["status"]
if status in ("SUCCEEDED", "FAILED"): break
time.sleep(5)
results = requests.get(
f"https://api.apify.com/v2/actor-runs/{run['id']}/dataset/items",
headers={"Authorization": "Bearer YOUR_APIFY_TOKEN"}
).json()
for profile in results:
print(f"@{profile['username']}: {profile['follower_count']:,} followers, {profile['video_count']} videos")
avg_views = sum(v.get('views',0) for v in profile.get('videos',[])) / max(len(profile.get('videos',[])),1)
print(f" Avg video views: {avg_views:,.0f}")
Anti-Detection Strategy
TikTok's bot detection is aggressive but focused on specific behaviors:
# Key anti-detection settings
import random, time
def safe_delay():
"""Human-like delay between requests."""
time.sleep(random.uniform(1.5, 4.0))
# Rotate these user agents
USER_AGENTS = [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36",
"Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 Version/17.0 Mobile/15E148 Safari/604.1",
]
# TikTok blocks datacenter IPs aggressively
# Use residential proxies for sustained scraping
PROXY = "http://user:pass@residential-proxy.com:8080"
Use Cases
Influencer marketing: Validate engagement rates before signing creators (follower count vs. actual views)
Competitive analysis: Track how competitor brands perform on TikTok — post frequency, engagement rates, trending topics
Trend research: Identify which hashtags and sounds are going viral before they peak
Creator discovery: Find micro-influencers in your niche with high engagement-to-follower ratios
Content strategy: Analyze what posting times and formats work best in your category
What You Can't Access
- Private account content — followers list not accessible even for public accounts
- DM/inbox data — requires account ownership
- Ad performance data — only accessible to advertisers via TikTok Ads API
- Historical data beyond 90 days — TikTok's API only returns recent content
The internal API approach works for research and monitoring at moderate scale. For ongoing bulk scraping (1000+ profiles/day), use proxies and Apify's managed solution to avoid re-engineering the auth flow every time TikTok changes their WAF.
Save hours on scraping setup: The $29 Apify Scrapers Bundle includes 35+ production-ready actors — Google SERP, LinkedIn, Amazon, TikTok, contact info, and more. Pre-configured inputs, working on day one.
Top comments (0)