~ / guides / How to Scrape TikTok Profiles (2026)

How to Scrape TikTok Profiles (2026)

AQ
Aria Quinn
TikTok data engineer · about the author
the short version
  • Profile data (followers, likes, bio, verified, video count) sits in a __UNIVERSAL_DATA_FOR_REHYDRATION__ script tag. One Python requests call with a browser User-Agent returned it as JSON for me in July 2026.
  • The five fields map to keys: followers = stats.followerCount, likes = stats.heartCount, videos = stats.videoCount, verified = user.verified, bio = user.signature.
  • A default Python User-Agent returned HTTP 403 with an empty body. A Chrome User-Agent flipped the same call to 200. Datacenter IPs and follower-list endpoints (X-Bogus / msToken) are where a raw script stalls.
  • For many profiles at once, a scraper API takes a username and returns the same parsed fields, with proxies and request signing handled server side.

I scraped my first TikTok profile of the day the lazy way: one requests.get against https://www.tiktok.com/@nasa with a browser User-Agent and nothing else. It returned 200, and the followers, likes, bio, verified flag, and video count were all sitting inside the HTML as JSON. No official API, no headless browser, no proxy for that first pull.

This is how to scrape TikTok profiles the way I ran it in July 2026: the exact Python that returns each profile field, the JSON key every field lands in, the point where a raw script stops scaling, and the managed route for pulling many profiles at once. Every code block below is code I ran against live TikTok pages.

What data can you scrape from a TikTok profile?

You can scrape five core fields from a TikTok profile - followers, likes, bio, and verified status, plus the video count - along with the identifiers you need to pull that creator’s videos later. Every one of these is already in the public profile page, so a logged-out request returns them without touching a hidden endpoint.

Here is where each field lands in the page JSON:

Profile fieldJSON keyNotes
Followersstats.followerCountInteger, public on every account
Total likes (hearts)stats.heartCountSum of hearts across the creator’s videos
Videosstats.videoCountCount of public posts
Followingstats.followingCountAccounts the creator follows
Verifieduser.verifiedBoolean, the blue check
Biouser.signatureFree text, may hold a contact email
Bio linkuser.bioLink.linkExternal URL, if set
Handleuser.uniqueIdThe @name
Display nameuser.nicknameShown above the bio
secUiduser.secUidOpaque id used to page the video feed
User iduser.idNumeric account id

The split that matters is between fields and feeds. The counts above (followerCount, heartCount, videoCount) are static values baked into the profile page, so they come back on the first request. The follower list, the video list, and comments are separate paginated feeds that load later from signed endpoints, which is a different problem covered further down. To read the counts, you just need to get the page and find the JSON.

How do you scrape a TikTok profile?

You scrape a TikTok profile by requesting its public page with a browser User-Agent and parsing the JSON that TikTok server-renders into the HTML. Every profile page ships with a <script id="__UNIVERSAL_DATA_FOR_REHYDRATION__"> tag, and the browser uses that JSON to hydrate the page. A scraper reads the same JSON directly, so you never render anything. The whole method is three steps.

Step 1: Request the profile page with a browser User-Agent

Install the one dependency and fetch the @handle URL. The User-Agent is the only header that matters at this stage.

pip install requests
import requests

UA = ("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
      "(KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36")

url = "https://www.tiktok.com/@nasa"
r = requests.get(url, headers={"User-Agent": UA}, timeout=25)
print(r.status_code)      # -> 200

Step 2: Extract the rehydration JSON

Pull the __UNIVERSAL_DATA_FOR_REHYDRATION__ script tag out of the HTML with a regex, then json.loads it. The profile lives under the webapp.user-detail scope, inside a userInfo object that holds both the user block and the stats block.

import re, json

m = re.search(
    r'<script id="__UNIVERSAL_DATA_FOR_REHYDRATION__"[^>]*>(.*?)</script>',
    r.text, re.S,
)
data = json.loads(m.group(1))
user_info = data["__DEFAULT_SCOPE__"]["webapp.user-detail"]["userInfo"]

Step 3: Read the five profile fields

Read the fields straight off the user and stats blocks. This prints the handle, display name, verified flag, bio, followers, total likes, and video count for @nasa.

user = user_info["user"]
stats = user_info["stats"]

print(user["uniqueId"])        # nasa   (the @handle)
print(user["nickname"])        # display name
print(user["verified"])        # True / False
print(user["signature"])       # bio text
print(stats["followerCount"])  # followers
print(stats["heartCount"])     # total likes (hearts)
print(stats["videoCount"])     # number of videos

Two caveats from my own runs. First, heartCount overflows on the biggest accounts: when I read very high-like creators such as @khaby.lame, the value came back negative, which is a 32-bit signed integer wrapping once total likes pass roughly 2.1 billion. Store likes as a 64-bit integer so you inherit TikTok’s number, not the overflow. Second, the follower and video counts drifted between repeat requests on some pulls, so treat the JSON shape as reliable and verify any single count against a second request before you report it. That kind of edge case only shows up when you scrape live pages instead of reading a tutorial. One profile is easy; the friction starts when you want a few hundred.

How do you scrape many TikTok profiles at once?

You scrape many TikTok profiles at once by looping the single-profile fetch over a list of handles, caching each secUid, and spacing the requests so TikTok does not rate-limit the run. Wrap the three steps above into a scrape_profile(handle) function that returns a dict, then iterate.

import time

def scrape_profile(handle):
    # steps 1-3 from above, returning the parsed fields as a dict
    ...

handles = ["nasa", "spacex", "natgeo"]
profiles = {}
for h in handles:
    profiles[h] = scrape_profile(h)
    time.sleep(3)                 # space out requests, avoid bursts

Cache the secUid for each account on that first pass. It is the opaque id TikTok wants when you later ask for a creator’s videos, and it never changes, so storing it means the video scrape skips a profile fetch entirely.

The boundary you hit is the follower list, not the count. Reading how many followers an account has is free from the profile JSON. Reading who those followers are, or paging a creator’s full video catalog, comes from internal endpoints that require a browser-minted X-Bogus signature and an msToken. A raw request to those returns an empty 200. The open-source TikTok-Api library drives Playwright so the page mints those signatures for you, which works but is heavy per profile and breaks whenever TikTok rotates its signing. Before any of that, though, the more common wall is simpler: the request comes back empty.

Why do TikTok profile scrapes come back empty or blocked?

TikTok profile scrapes come back empty or blocked for three reasons, in order of how often they bite: a non-browser User-Agent, a datacenter IP, or a request rate that trips TikTok’s bot checks. The first one is the cheapest to fix and the one that stops most first-time scrapers.

The single most useful test I ran was swapping one header. These two requests differ by the User-Agent and nothing else:

RequestUser-AgentStatusBody
GET /@nasaPython default (python-requests/2.x)4030 bytes
GET /@nasaChrome 126 desktop string200Full profile HTML

A blank 403 is the signature of a missing or non-browser User-Agent, so set a real Chrome string before anything else. After that, the IP matters: TikTok flags datacenter and cloud ranges (AWS, GCP, Azure), so the same script that works from your laptop returns an empty shell from a server. Residential or mobile IPs that present as ordinary home connections last far longer, and a steady cadence of one request every few seconds survives where parallel bursts get throttled.

One accuracy note on what is fenced off. TikTok’s robots.txt blocks a long list of named crawlers (GPTBot, ClaudeBot, CCBot, Bytespider and others) with a flat Disallow: /, and for the catch-all User-agent: * it disallows /search?, /search/user?q=, several /api/ paths, and the /embed/@ routes. It does not list /@username profile paths as disallowed for the generic crawler. That file is a published directive that states TikTok’s automation policy; it carries no technical enforcement on its own, and blocking is handled separately by the IP and header checks above. Fixing those signals yourself is a standing chore, which is why the next section hands it off.

How do you scrape TikTok profiles without proxies or signing?

You scrape TikTok profiles without proxies or signing by sending the username to a scraper API and getting the same parsed fields back, with the IP rotation and X-Bogus signing handled server side. You send one authenticated request. You get structured data. There is no 403 to debug and no signer to maintain.

With ChocoData, a profile pull is a single GET. The TikTok endpoints live under the tiktok path, and you pass your key as api_key:

curl "https://chocodata.com/api/v1/tiktok/profile?username=nasa&api_key=$CHOCO_API_KEY"

The Python version is just as short and returns the same user and stats blocks you would have parsed by hand, already cleaned:

import os, requests

resp = requests.get(
    "https://chocodata.com/api/v1/tiktok/profile",
    params={"username": "nasa", "api_key": os.environ["CHOCO_API_KEY"]},
    timeout=30,
)
profile = resp.json()
print(profile["stats"]["followerCount"])   # followers
print(profile["stats"]["heartCount"])       # total likes
print(profile["user"]["signature"])         # bio
print(profile["user"]["verified"])          # verified
print(profile["stats"]["videoCount"])       # videos

The free tier is 1,000 requests with no card, then it is usage-based (Pro is $0.60 per 1,000 requests), and you are billed only for successful requests. The trade is straightforward: for a one-off pull of a few public profiles, the raw requests script at the top of this guide is genuinely all you need and it is free. For continuous collection across hundreds of creators, datacenter IPs get blocked and the follower feed needs signing, so offloading both is usually cheaper than your own time once you price it in.

The official route does not fit most builders. TikTok’s Research API returns rich profile data but is gated to approved academic and non-profit researchers, which rules out commercial use, so reading the public page is the open path. The full Python build is in how to scrape TikTok with Python, and I rank the managed options head to head in best TikTok scrapers in 2026.

Scraping public TikTok profiles that a logged-out visitor can already see sits on the safer side of US case law, though personal data and TikTok’s terms are separate questions. The Ninth Circuit in hiQ Labs v. LinkedIn held that scraping public pages is not unauthorized access under the CFAA, which is the ruling most public-data collection leans on.

A later decision pointed the same way on terms of service: in Meta v. Bright Data the Northern District of California found that logged-out scraping of public data does not breach a platform’s terms, an outcome summarized in this Farella Braun analysis. Logged-in access, private accounts, and TikTok’s own Terms of Service are outside that shelter, so they stay a separate question.

The other line is personal data. A TikTok handle, bio, and follower count are personal data under GDPR and similar laws, so if you collect fields tied to identifiable people you need a lawful basis and should minimize what you keep. This is general information, not legal advice, so confirm your specific use with counsel. I work through TikTok’s Terms of Service and the personal-data angle in full in is scraping TikTok legal.

FAQ

Can you scrape a TikTok profile without an API key?

Yes, for public profiles. TikTok server-renders the profile into a __UNIVERSAL_DATA_FOR_REHYDRATION__ script tag that a plain requests.get with a browser User-Agent can fetch and json.loads can parse. That gives you followers, likes, bio, verified status and video count. The limit is volume: datacenter IPs get blocked and the follower list endpoint needs a signed request, so a keyless script covers a handful of profiles and stalls past that.

How do you scrape a private TikTok profile?

You cannot pull a private TikTok profile's videos or follower list by scraping the public page. A private account hides its posts behind follow approval, so the page JSON returns the identity fields (handle, nickname, bio, verified) and the privateAccount flag but not the video feed. Only data a logged-out visitor can already see is available to a scraper.

How do you get a TikTok creator's email from their profile?

Some creators publish a contact email in the public bio, which you read from the user.signature field, alongside the external URL in user.bioLink.link. Not every profile has one, and business accounts sometimes surface a separate email button that is not in the page JSON. A regex over the parsed signature string catches the addresses that are there.

What is secUid and why do you need it to scrape a profile's videos?

The secUid is the opaque user id TikTok requires when you request a creator's video list, and you cannot guess it. You read it once from the profile JSON (user.secUid) and reuse it as the key for the item-list endpoint. Caching it per account means you skip a profile fetch on later runs.

Can you scrape a TikTok profile's follower list?

The follower count is free (it is in the profile JSON as stats.followerCount), but the follower list is not. The list of accounts that follow a creator loads from a signed internal endpoint that needs a browser-minted X-Bogus signature and an msToken, so a raw request returns an empty body. That feed is where most keyless follower scrapers stop.

AQ
Aria Quinn
I've built TikTok data pipelines for years. On tiktokscraperapi.com I run TikTok scraping methods against live pages and publish what actually holds up.