jsonscraper

TikTok-thema’s van makers analyseren: een praktische Python-pijplijn

Zo haal je met de TikTok Scraper API een openbare feed op, bewaar je de oorspronkelijke antwoorden en bereid je een herhaalbare analyse van posts voor.

Redactioneel beleid Een fout melden

Wanneer een team een onderwerp zoekt voor de volgende campagne, verandert het handmatig bekijken van tientallen profielen al snel in een verzameling notities zonder vaste methode. De ene analist noteert weergaven, de andere videobijschriften, en posts met vergelijkbare formuleringen belanden in verschillende spreadsheets. Een week later is het lastig vast te stellen wat vaker terugkomt: een onderwerp, een presentatievorm of gewoon een geslaagde video.

Artikel: TikTok-thema’s van makers analyseren: een praktische Python-pijplijn
Samenvatting: We leggen uit hoe je met Python het monitoren van openbare TikTok-accounts instelt: controleer het endpoint en de parameters in Postman, bewaar API-antwoorden, normaliseer bevestigde velden en vergelijk posts in de tijd.
Beeldfunctie: omslag — het centrale idee
Sectie: 
Visueel onderwerp: redactionele foto van geanonimiseerde korte-video-tegels naast datakaarten met tijdstempels en themalabels op een onderzoekstafel, als illustratie van een
© jsonscraper · door AI gegenereerde illustratie

Een praktische aanpak is een korte lijst met openbare accounts bij te houden, regelmatig gegevens over hun video’s in gestructureerde vorm op te halen en elke verzameling als een afzonderlijke momentopname op te slaan. Vervolgens kun je posts en beschikbare statistieken in de tijd vergelijken en een taalmodel gebruiken om bijschriften voorlopig in groepen in te delen. Hieronder staat een opzet voor zo’n onderzoekspijplijn in Python met de TikTok Scraper API van jsonscraper.

Formuleer vóór het verzamelen je onderzoeksvraag

Stel je een marketingteam van een klein merk voor sportvoeding voor. Het wil weten welke onderwerpen regelmatig verschijnen bij geselecteerde openbare TikTok-makers en welke video’s het handmatig moet bekijken. Het doel is posts van vooraf gekozen accounts gedurende een observatieperiode te vergelijken, niet een universele populariteitsranglijst van TikTok samen te stellen.

Daarmee zijn de grenzen van de analyse bepaald. De feed van geselecteerde profielen verzamelen helpt om de inhoud en publicatiefrequentie van die accounts te onderzoeken. Beschikbare openbare tellers kun je vastleggen op het moment van het verzoek. Voor het beoordelen van de resultaten van eigen advertenties zijn afzonderlijke gegevens nodig, bijvoorbeeld uit het advertentiesysteem of de webanalyse over uitgaven en conversies.

Leg vóór je de API aansluit het onderzoeksprotocol vast: de lijst met accounts, de startdatum, de verzamelinterval, de te analyseren velden en de criteria voor het opnemen van posts. Noteer het tijdstip van elk verzoek. Zo kun je veranderingen in de statistieken van één video onderscheiden van verschillen tussen twee verzamelingen waarnemingen.

Wat je verzamelt en berekent

Voor een klein project zijn drie gegevenslagen nodig. De eerste bevat de account-ID en het tijdstip waarop de verzameling is gestart. De tweede is het oorspronkelijke API-antwoord, opgeslagen zodat je het later kunt controleren. De derde bestaat uit genormaliseerde velden voor zoekopdrachten en rapporten: video-ID, bijschrift, publicatietijd en beschikbare interactietellers.

De veldnamen en de structuur van het antwoord moet je vaststellen aan de hand van een voorbeeld van de specifieke endpoint. Ga er niet op voorhand van uit dat de lijst altijd videos heet of dat de weergaventeller views heet. Voer eerst een gedocumenteerd verzoek uit en bekijk de daadwerkelijke JSON. Stel daarna de omzetting naar je eigen schema in.

Nuttige statistieken zijn het aantal nieuwe posts per interval, de verdeling van posts over onderwerpen en de verandering van openbare tellers tussen momentopnamen van dezelfde video. Vergelijk voor die laatste statistiek records met overeenkomende video-ID’s. Zo blijft de ontwikkeling van een al gepubliceerde video gescheiden van de statistieken van nieuwe posts.

De TikTok Scraper API aansluiten

De beschrijving van de TikTok Scraper API vermeldt het basisadres https://tiktok.evelode.com. De endpointdocumentatie bevestigt GET /getUserFeed en de parameters query, max_cursor, count, region, with_pinned_posts, sort_type en cache_timeout. Voor het eerste verzoek hoef je alleen een profiel in te vullen bij query en bijvoorbeeld het aantal items op te geven via count. De sleutel license_key wordt als querystringparameter meegestuurd; de configuratie ervan wordt ook beschreven in de API-documentatie. In de Postman-collectie kun je het endpoint controleren en het antwoord testen voordat je de integratie bouwt.

Bewaar de sleutel in een omgevingsvariabele. Neem hem niet op in broncode, een repository, spreadsheet of clientapplicatie. Voer een verzoek uit, sla een geslaagd JSON-voorbeeld op met de datum en de naam van het endpoint en gebruik dat als basis voor de normalisatieadapter en tests.

Een minimale Python-aanvraag

Volgens de documentatie bevat het antwoord van de gebruikersfeed een externe status en een object tiktok, waarin de lijst met posts zich bevindt in aweme_list. Records kunnen een ID, bijschrift, publicatietijd, auteur en statistieken bevatten. Controleer de concrete velden en waarden aan de hand van het ontvangen antwoord: sommige gegevens kunnen ontbreken.

import json
import os
from datetime import datetime, timezone
from pathlib import Path

import requests

API_KEY = os.environ["JSONSCRAPER_TIKTOK_LICENSE_KEY"]
ENDPOINT_URL = "https://tiktok.evelode.com/getUserFeed"


def fetch_user_feed(handle: str, count: int = 20) -> dict:
    response = requests.get(
        ENDPOINT_URL,
        params={
            "license_key": API_KEY,
            "query": handle,
            "count": count,
            "region": "US",
        },
        timeout=45,
    )
    response.raise_for_status()
    payload = response.json()
    if not isinstance(payload, dict):
        raise ValueError("Een JSON-object werd verwacht")
    if payload.get("status") != "ok":
        raise RuntimeError(f"API-status: {payload.get('status')!r}")
    tiktok = payload.get("tiktok")
    if not isinstance(tiktok, dict):
        raise ValueError("Het object tiktok ontbreekt in het antwoord")
    return payload


def save_raw(payload: dict, account: str, output_dir: str = "data/raw") -> Path:
    collected_at = datetime.now(timezone.utc).isoformat()
    safe_account = "".join(c for c in account if c.isalnum() or c in "-_@")
    path = Path(output_dir) / f"{safe_account}_{collected_at.replace(':', '-')}.json"
    path.parent.mkdir(parents=True, exist_ok=True)
    path.write_text(
        json.dumps(
            {"collected_at": collected_at, "account": account, "payload": payload},
            ensure_ascii=False,
            indent=2,
        ),
        encoding="utf-8",
    )
    return path


def normalize_items(payload: dict, account: str, collected_at: str) -> list:
    items = payload["tiktok"].get("aweme_list", [])
    if not isinstance(items, list):
        raise ValueError("Het veld tiktok.aweme_list is geen lijst")

    observations = []
    for item in items:
        if not isinstance(item, dict):
            continue
        stats = item.get("statistics")
        stats = stats if isinstance(stats, dict) else {}
        author = item.get("author")
        author = author if isinstance(author, dict) else {}
        observations.append({
            "account_handle": account,
            "collected_at": collected_at,
            "video_id": item.get("aweme_id"),
            "caption": item.get("desc"),
            "published_at_epoch": item.get("create_time"),
            "author_handle": author.get("unique_id"),
            "views": stats.get("play_count"),
            "likes": stats.get("digg_count"),
            "comments": stats.get("comment_count"),
            "shares": stats.get("share_count"),
        })
    return observations


if __name__ == "__main__":
    account = "creator_handle"
    payload = fetch_user_feed(account, count=20)
    collected_at = datetime.now(timezone.utc).isoformat()
    raw_path = save_raw(payload, account)
    observations = normalize_items(payload, account, collected_at)
    print(f"Opgeslagen: {raw_path}; records: {len(observations)}")

Stel vóór het uitvoeren JSONSCRAPER_TIKTOK_LICENSE_KEY in de omgeving in en installeer de bibliotheek requests. De code controleert het HTTP-antwoord, de externe status en de aanwezigheid van het object tiktok, en leest daarna aweme_list. De ruwe JSON wordt opgeslagen en de velden die in de documentatie zijn bevestigd, worden uitgelezen; ontbrekende waarden blijven leeg. De opgehaalde feed is de verzameling resultaten die de API teruggeeft. Koppel het rapport daarom aan het tijdstip van het verzoek en het geselecteerde profiel.

Bewaar momentopnamen en vergelijk posts

Voor een klein project zijn SQLite of PostgreSQL geschikt. Bewaar het ruwe antwoord apart van de genormaliseerde records. Voor de tabel met waarnemingen kun je bijvoorbeeld dit schema gebruiken:

CREATE TABLE IF NOT EXISTS video_observations (
    account_handle TEXT NOT NULL,
    video_id TEXT NOT NULL,
    collected_at TEXT NOT NULL,
    published_at_epoch INTEGER,
    caption TEXT,
    views INTEGER,
    likes INTEGER,
    comments INTEGER,
    shares INTEGER,
    raw_file TEXT,
    PRIMARY KEY (account_handle, video_id, collected_at)
);

Elke uitvoering voegt een nieuwe momentopname toe in plaats van de vorige te overschrijven. Vergelijk tellers alleen wanneer er voor dezelfde video twee waarden beschikbaar zijn. Vermeld het interval tussen de verzoeken en de observatietijd in het rapport: die geven aan over welke periode de verandering is opgebouwd.

Begin voor thematische groepering met een kleine woordenlijst van categorieën en voeg zo nodig later een classificatiemodel of taalmodel toe. Geef het model opgeschoonde bijschriften, post-ID’s en vooraf bepaalde categorieën. Een gestructureerd resultaat met een categorie en een korte toelichting is gemakkelijker tussen uitvoeringen te vergelijken dan een vrije beschrijving.

Voeg een taalmodel toe met controleerbare labels

Een model kan bijschriften voorlopig indelen in onderwerpen als ‘recepten’, ‘trainingen’, ‘productrecensies’ en ‘persoonlijke verhalen’. Label eerst handmatig enkele tientallen posts. Vergelijk de automatische labels met die voorbeelden, verduidelijk de categoriedefinities en herhaal de evaluatie nadat je de prompt of het model hebt aangepast.

Bereken het aantal nieuwe posts, de mediaan van de tellers en het verschil tussen momentopnamen betrouwbaarder met gewone code. Gebruik het model voor tekstclassificatie en korte toelichtingen. Zorg dat de oorspronkelijke bijschriften en numerieke waarnemingen beschikbaar blijven voor controle.

Bewaar bij elk label ook de post-ID, de promptversie, de verwerkingsdatum en het gebruikte model. Bij een verkeerde classificatie kan een analist het bijschrift terugvinden en de regel aanpassen. Het is nuttig het oorspronkelijke label en een handmatige correctie apart op te slaan.

Automatiseer de uitvoering

Verplaats het script na een geslaagde handmatige test naar cron, GitHub Actions, n8n of Make. De planner verzamelt gegevens volgens een schema, geeft de lijst met accounts door, registreert het resultaat en stuurt het rapport naar de gekozen opslaglocatie. Bewaar de sleutel in de geheimen van de runtime-omgeving. Test het proces eerst met één account en breid de lijst daarna uit.

Verdeel de automatisering in stappen: een wachtrij met accounts, de API-aanroep, opslag van het ruwe antwoord, normalisatie, opslag van de momentopname en voorbereiding van het rapport. Een fout bij één account mag de resultaten van de andere accounts niet wissen. Je kunt herhaalde uitvoeringen idempotent maken met een uitvoerings-ID en unieke beperkingen in de database.

Leg het tijdstip, het account, het endpoint, de HTTP-status, de duur, het aantal verwerkte items en de foutbeschrijving vast in een logboek. Schrijf de API-sleutel niet naar het logboek. De parameter cache_timeout wordt vermeld voor /getUserFeed; voeg die aan het verzoek toe als je een bepaalde cacheduur nodig hebt. In de API-documentatie staat dat de standaardwaarde 3600 seconden is.

Controleer de kwaliteit voordat je het rapport publiceert

Vergelijk enkele genormaliseerde records met de oorspronkelijke JSON. Controleer of een nieuwe verzameling dezelfde video aan de hand van de ID herkent, datums op de verwachte manier worden geïnterpreteerd, numerieke velden het juiste type hebben en het aandeel ontbrekende waarden bekend is. Voer daarna een tweede keer de verzameling uit en controleer of de database de oude waarnemingen heeft behouden en nieuwe heeft toegevoegd.

Vermeng geen accounts of verzamelperioden. Gebruik voor de vergelijking van onderwerpen perioden van gelijke lengte of vermeld de lengte duidelijk in het rapport. Leg voor de ontwikkeling van tellers de tijd tussen momentopnamen vast, zodat de lezer de omvang van de vergeleken intervallen kent.

Bewaar de oorspronkelijke tekst van het bijschrift en maak daarnaast een opgeschoonde versie. Emoji’s, hashtags, links en taalkenmerken kunnen de classificatie beïnvloeden. Met afzonderlijke velden kun je dat effect controleren en categorieën opnieuw berekenen zonder de API opnieuw aan te roepen.

Wat de pijplijn oplevert

Na enkele cycli beschikt het team over een tabel met posts en momentopnamen, een voorlopige thematische groepering van bijschriften en een rapport over nieuwe video’s in de gekozen periode. Dit helpt om video’s te selecteren voor een deskundige beoordeling, terugkerende onderwerpen bij de gekozen accounts te zien en veranderingen in openbare tellers tussen observatiedata te controleren.

Op basis van deze gegevens kun je hypotheses voor een redactionele kalender formuleren: vergelijk manieren om hetzelfde onderwerp te presenteren of selecteer onderwerpen om in eigen content te testen. Om het commerciële effect te beoordelen, vergelijk je de waarnemingen met interne campagnegegevens.

Kies om te beginnen een korte lijst met openbare accounts en controleer GET /getUserFeed in de Postman-verzameling met verzoeken. Neem alleen parameters en veldpaden in de code op die zijn bevestigd door de documentatie van het endpoint en het daadwerkelijke antwoord.

Verantwoord omgaan met openbare gegevens

Beperk de lijst met accounts tot het onderzoeksdoel, verzamel alleen de benodigde velden en stel een bewaartermijn in voor het ruwe antwoord. Controleer vóór commercieel gebruik van de gegevens de toepasselijke platformvoorwaarden en privacyvereisten in jouw rechtsgebied. Toegangsbeheer en het verwijderen van verouderde momentopnamen helpen het proces binnen de grenzen van de opdracht te houden.

Verwijder velden die het model niet nodig heeft voordat je gegevens naar een AI-dienst stuurt. Vermeld in het rapport de post-ID en observatiedatum, zodat een medewerker de record kan openen en de onderbouwing van de conclusie kan controleren.

Korte checklist voor de start

  1. Bepaal de niche, de accountlijst, de periode en de analysevragen.
  2. Controleer de parameters van GET /getUserFeed in de documentatie en het daadwerkelijke antwoord in Postman.
  3. Sla een JSON-voorbeeld op en stel de normalisatie in op basis van bevestigde velden.
  4. Sla het ruwe antwoord en afzonderlijke momentopnamen met de verzameltijd op.
  5. Bereken numerieke statistieken met code en gebruik AI voor een voorlopige groepering van tekst.
  6. Voeg een planning, logging, afhandeling van herhaalde pogingen en een bewaartermijn toe.

Zo wordt monitoring een reproduceerbaar onderzoek: elke conclusie is gekoppeld aan een post en observatietijd, en de code is gebaseerd op de daadwerkelijke structuur van het gekozen endpoint.

People

No people listed for this article yet.

Keep readingTikTok-zoekresultaten archiveren met Python
Read the next article

Maak van wat je leest een werkende integratie

Ontdek de socialdata-API's van jsonscraper, test aanvragen en bouw je volgende workflow.

API's verkennen