DEV Community

Vhub Systems
Vhub Systems

Posted on

How to Scrape TikTok Creator Profiles and Video Stats Without the API in 2026

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))
Enter fullscreen mode Exit fullscreen mode

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]}")
Enter fullscreen mode Exit fullscreen mode

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}")
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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.

Get the Bundle ($29) →

Top comments (0)