TikTok- und Instagram-Interaktionsdaten als JSON Auslesen
Wenn du je versucht hast, ein TikTok-Video oder einen Instagram-Beitrag mit einer einfachen HTTP-Anfrage auszulesen, kennst du die zwei Probleme bereits. Die Seite kommt fast leer zurück, und die Zahlen, die du siehst, sind auf Werte wie “1,2 Mio. Aufrufe” gerundet. Für Social Listening, das Prüfen von Influencern oder Kampagnenberichte reicht “1,2 Mio.” nicht aus. Du brauchst die exakte ganze Zahl.
Dieser Leitfaden erklärt, warum diese beiden Seiten schwer auszulesen sind, wo die echten Zahlen innerhalb der Seite tatsächlich liegen und wie du exakte Interaktionsdaten als strukturiertes JSON extrahierst. Alles hier ist mit Open-Source-Werkzeugen reproduzierbar, und am Ende behandeln wir die Abkürzung für Teams, die diese Klempnerei lieber nicht warten möchten.
Warum TikTok und Instagram Sich Wehren
Beide Plattformen sind Single-Page-Anwendungen. Das HTML, das deine erste Anfrage erhält, ist ein Gerüst: ein paar Meta-Tags, ein Titel und ein Bündel JavaScript. Der Inhalt, den du in einem echten Browser siehst, wird erst nach dem Laden der Seite aufgebaut, wenn dieses JavaScript läuft und das DOM mit den Daten hydriert.
Das hat zwei Folgen für das Scraping:
- Eine einfache Anfrage liefert fast nichts. Werkzeuge wie
requestsoder ein nacktesfetchführen das JavaScript nie aus, also steht der sichtbare Text - Beschreibungen, Zahlen, Benutzernamen - schlicht nicht im Antworttext. Du bekommst einen Seitentitel und kaum mehr. - Die sichtbaren Zahlen sind für Menschen, nicht für Maschinen. Wenn die Seite doch rendert, zeigt sie abgekürzte Zahlen: “1,2 Mio.”, “34,5 Tsd.”, “980”. Diese Zeichenketten sind verlustbehaftet. Aus “1,2 Mio.” kannst du den exakten Wert nicht wiederherstellen, und die Rundungsgrenzen verschieben sich über die Zeit.
Obendrein führen beide Seiten Anti-Bot-Prüfungen, Ratenbegrenzungen und Login-Schranken aus, sodass naives Scraping schnell gedrosselt oder blockiert wird.
Wo die Echten Zahlen Wirklich Liegen
Hier die gute Nachricht. Auch wenn der sichtbare Text gerundet ist, sind die exakten Ganzzahlen fast immer in der Seite vorhanden, nur nicht dort, wo du hinschaust. Moderne SPAs liefern eine eingebettete JSON-Nutzlast mit, damit die App sofort hydrieren kann. Diese Nutzlast trägt die präzisen Daten.
- TikTok bettet einen großen JSON-Block in ein Script-Tag ein, historisch
SIGI_STATEund in jüngerer Zeit__UNIVERSAL_DATA_FOR_REHYDRATION__. Darin findest du Felder wieplayCount,diggCount(Likes),commentCount,shareCountundcollectCount(Speicherungen) als echte Zahlen. - Instagram stellt Beitragsdaten über eingebettetes JSON und seine internen GraphQL-Antworten bereit. Ein Beitragsobjekt enthält typischerweise
edge_media_preview_like.count,edge_media_to_comment.count, denusernamedes Eigentümers undtaken_at_timestamp.
Der Trick ist, aufzuhören, den gerenderten Text auszulesen, und stattdessen die eingebettete Nutzlast zu lesen. Dort wird aus “1,2 Mio.” die Zahl 1203481.
Das Eingebettete JSON Selbst Extrahieren
Du musst die Seite trotzdem rendern oder zumindest die Anti-Bot-Schicht überwinden, bevor du dieses Script-Tag lesen kannst. Ein Headless-Browser erledigt beides. Playwright ist eine gute Standardwahl, weil es einen echten Chromium-Build steuert und dich auf das Erscheinen der Nutzlast warten lässt.
import json
from playwright.sync_api import sync_playwright
def scrape_tiktok(url: str) -> dict:
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
page.goto(url, wait_until="networkidle")
# Lies die eingebettete Hydrations-Nutzlast statt des gerenderten Texts
raw = page.locator(
"script#__UNIVERSAL_DATA_FOR_REHYDRATION__"
).inner_text()
browser.close()
data = json.loads(raw)
scope = data["__DEFAULT_SCOPE__"]["webapp.video-detail"]
stats = scope["itemInfo"]["itemStruct"]["stats"]
return {
"plays": int(stats["playCount"]),
"likes": int(stats["diggCount"]),
"comments": int(stats["commentCount"]),
"shares": int(stats["shareCount"]),
"saves": int(stats["collectCount"]),
}
Der exakte Schlüsselpfad verschiebt sich über die Zeit, behandle ihn also als etwas, das du warten wirst. Ein robusteres Muster ist, das JSON zu laden und es nach dem stats-Objekt zu durchsuchen, statt den vollen Pfad fest zu codieren.
Für Instagram gilt dieselbe Idee, aber die saubersten Daten bekommst du oft, indem du die GraphQL-Antwort abfängst, die die App stellt, statt ein statisches Script-Tag zu parsen:
from playwright.sync_api import sync_playwright
def scrape_instagram(url: str) -> dict:
result = {}
def on_response(response):
if "graphql/query" in response.url and response.status == 200:
try:
media = response.json()["data"]["xdt_shortcode_media"]
except Exception:
return
result.update({
"likes": media["edge_media_preview_like"]["count"],
"comments": media["edge_media_to_comment"]["count"],
"author_username": media["owner"]["username"],
"posted_at": media["taken_at_timestamp"],
})
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
page.on("response", on_response)
page.goto(url, wait_until="networkidle")
browser.close()
return result
Das Abfangen von Antworten ist mächtig, weil es genau die Nutzlast erfasst, die die App selbst verwendet. Du liest dieselben Zahlen, die die Oberfläche liest, bevor sie sie zur Anzeige rundet.
Bei Großem Umfang Unblockiert Bleiben
Ein Video funktioniert von deinem Laptop aus problemlos. Tausend Videos pro Stunde von einer einzigen IP nicht. Wenn du in großem Umfang sammeln willst, plane das Anti-Bot-Problem von vornherein ein:
- Rotiere Residential-IPs. Rechenzentrums-IPs werden auf beiden Plattformen schnell markiert. Leite Anfragen über rotierende Residential-Proxys, damit jede Anfrage wie ein anderer gewöhnlicher Nutzer aussieht.
- Drossle und streue. Füge zufällige Verzögerungen zwischen Anfragen ein. Vorhersehbarer, maschinengetakteter Verkehr ist eines der am leichtesten erkennbaren Signale.
- Verwende realistische Browser-Fingerprints wieder. Nicht erkennbare Browser-Builds und konsistente Header reduzieren Signale automatisierter Clients. Mische keinen mobilen User Agent mit einem Desktop-Viewport.
- Behandle den Fall der leeren Hülle. Bekommt dein Extraktor eine Seite ohne Nutzlast, behandle das als weiche Blockade und wiederhole es später, statt eine Null zu erfassen.
Nichts davon ist exotisch, aber es ist laufende Arbeit. Selektoren verschieben sich, GraphQL-Formen ändern sich und die Blockierung wird nachjustiert. Diese Wartung ist der echte Preis dafür, es selbst zu bauen.
Die Abkürzung: Um Fertig Geparstes JSON Bitten
Wenn du dir die Browser-Flotte und die Nutzlast-Archäologie sparen willst, kannst du die geparsten Daten direkt anfordern. ScrapeUnblocker übernimmt das Rendern und die Anti-Bot-Schicht für dich, und sein Parsed-Data-Modus liest die eingebettete Nutzlast in deinem Namen, sodass du exakte Ganzzahlen statt des gerundeten Texts erhältst, den die Seite malt.
Mit parsed_data=true liefert die URL eines TikTok-Videos plays, likes, comments, shares und saves zurück, und ein Instagram-Beitrag liefert exakte likes und comments, den echten author.username und ein echtes posted_at. Du schickst eine URL, du bekommst sauberes JSON, und nicht du bist derjenige, der die Selektoren wartet, wenn sich das Markup ändert.
import requests
resp = requests.get(
"https://api.scrapeunblocker.com/getPageSource",
params={
"url": "https://www.tiktok.com/@user/video/1234567890",
"parsed_data": "true",
},
headers={"Authorization": "Bearer YOUR_API_KEY"},
)
data = resp.json()
print(data["plays"], data["likes"], data["comments"])
Siehe den Leitfaden zu geparsten Daten für die vollständige Feldliste und die Parameter.
Häufige Fragen
Warum wirken die Zahlen, die ich auslese, gerundet? Weil du den Text liest, den die Oberfläche für Menschen rendert und der abgekürzt ist (“1,2 Mio.”). Die exakte Ganzzahl liegt in der eingebetteten JSON-Nutzlast oder der GraphQL-Antwort, nicht im sichtbaren DOM-Text. Parse die Nutzlast, und du erhältst die echte Zahl.
Kann ich das ohne einen Headless-Browser machen? Manchmal. Wenn du das eingebettete JSON oder einen JSON-Endpunkt direkt erreichst, kann eine gut geformte HTTP-Anfrage funktionieren. In der Praxis schützen beide Plattformen diese Antworten hinter Anti-Bot-Prüfungen, also sind ein echter Browser oder eine Scraping-API, die die Seite rendert, der zuverlässige Weg.
Ist es legal, TikTok und Instagram auszulesen? Das Auslesen öffentlich sichtbarer Daten wird in der Regel anders behandelt als der Zugriff auf private oder login-geschützte Inhalte, aber die Regeln hängen von deiner Rechtsordnung, den Plattformbedingungen und deiner Nutzung der Daten ab. Sammle nur öffentliche Daten, vermeide personenbezogene Daten, die du nicht brauchst, und hole für alles Kommerzielle Rechtsrat ein.
Wie vermeide ich, blockiert zu werden? Rotiere Residential-IPs, füge zufällige Verzögerungen ein, verwende realistische Browser-Fingerprints und wiederhole weiche Blockaden, statt Nullen zu erfassen. Bei großem Umfang nimmt dir eine Unblocking-API den Großteil dieser Arbeit ab, weil sie Rendern und Rotation für dich verwaltet.
Zum Abschluss
Der Grund, warum sich soziale Interaktionsdaten schwer auslesbar anfühlen, ist ein Missverhältnis: Du liest gerundeten Text, während die exakten Zahlen eine Schicht tiefer in einer eingebetteten JSON-Nutzlast sitzen. Sobald du diese Nutzlast statt des DOM liest, werden TikTok und Instagram zu einer weiteren strukturierten Quelle - Aufrufe, Likes, Kommentare, geteilte Beiträge, Speicherungen, Benutzernamen und Zeitstempel, alles als saubere Ganzzahlen.
Baue es selbst mit Playwright, wenn du volle Kontrolle willst, oder lass ScrapeUnblocker das geparste JSON direkt zurückgeben, wenn du deine Zeit lieber der Analyse widmest als der Klempnerei.
ScrapeUnblocker kostenlos testen
Über 95 % Erfolgsquote · ab 0,55 € pro 1.000 Aufrufe · 500 kostenlose Anfragen bei der Registrierung.