jsonscraper

Jak analizować tematy twórców TikToka: praktyczny pipeline w Pythonie

Jak pobierać publiczny feed za pomocą TikTok Scraper API, zapisywać surowe odpowiedzi i przygotować powtarzalną analizę publikacji.

Polityka redakcyjna Zgłoś błąd

Gdy zespół szuka tematu do następnej kampanii, ręczne przeglądanie dziesiątek profili szybko zamienia się w zbiór notatek pozbawionych wspólnej metodologii. Jeden analityk zapisuje wyświetlenia, drugi — podpisy filmów, a publikacje o podobnym brzmieniu trafiają do różnych tabel. Po tygodniu trudno ustalić, co powtarza się częściej: temat, forma przekazu czy po prostu udany film.

Artykuł: Jak analizować tematy twórców TikToka: praktyczny pipeline w Pythonie
Podsumowanie: Pokazujemy, jak skonfigurować monitoring publicznych kont TikToka w Pythonie: sprawdzić endpoint i parametry w Postmanie, zapisywać odpowiedzi API, normalizować potwierdzone pola i porównywać publikacje w czasie.
Rola obrazu: okładka — główna idea
Sekcja: 
Temat wizualny: Redakcyjna fotografia zanonimizowanych kafelków krótkich filmów ułożonych obok kart danych z oznaczeniami czasu i etykietami tematów na stole badawczym, ukazująca
© jsonscraper · ilustracja wygenerowana przez AI

Praktycznym rozwiązaniem jest prowadzenie krótkiej listy publicznych kont, regularne pobieranie ustrukturyzowanych informacji o ich filmach i zapisywanie każdego pobrania jako osobnego zrzutu. Następnie można porównywać publikacje i dostępne metryki w czasie, a model językowy wykorzystać do wstępnego grupowania podpisów. Poniżej przedstawiamy schemat takiego badawczego pipeline’u w Pythonie z TikTok Scraper API od jsonscraper.

Przed pobieraniem danych określ pytanie badawcze

Wyobraźmy sobie zespół marketingowy niewielkiej marki suplementów sportowych. Chce ustalić, jakie tematy regularnie pojawiają się u wybranych publicznych twórców TikToka i które filmy warto obejrzeć ręcznie. Zadaniem jest porównanie publikacji wcześniej wybranych kont w okresie obserwacji, a nie stworzenie uniwersalnego rankingu popularności TikToka.

To wyznacza granice analizy. Pobieranie feedu wybranych profili pomaga badać treść i częstotliwość publikacji tych kont. Dostępne publiczne liczniki można zapisywać w chwili wysłania zapytania. Do oceny wyników własnej reklamy potrzebne będą odrębne dane — na przykład wydatki i konwersje z systemu reklamowego lub analityki internetowej.

Przed podłączeniem API zapisz protokół badania: listę kont, datę rozpoczęcia, częstotliwość pobierania, analizowane pola i kryteria uwzględniania publikacji. Zapisuj czas każdego zapytania. Dzięki temu można odróżnić zmianę metryki jednego filmu od różnicy między dwoma zestawami obserwacji.

Co zbierać i co mierzyć

W niewielkim projekcie potrzebne są trzy warstwy danych. Pierwsza to identyfikator konta i czas rozpoczęcia pobierania. Druga — surowa odpowiedź API zachowana do późniejszej weryfikacji. Trzecia — znormalizowane pola na potrzeby zapytań i raportów: ID filmu, podpis, czas publikacji i dostępne liczniki interakcji.

Nazwy pól i zagnieżdżenie odpowiedzi trzeba ustalić na podstawie przykładu konkretnego endpointu. Nie zakładaj z góry, że lista zawsze nazywa się videos, a licznik wyświetleń — views. Najpierw wykonaj udokumentowane zapytanie i sprawdź rzeczywisty JSON, a potem skonfiguruj konwersję do własnego schematu.

Przydatne wskaźniki to liczba nowych publikacji w przedziale czasu, rozkład publikacji według tematów oraz zmiana publicznych liczników między zrzutami tego samego filmu. W tym ostatnim przypadku porównuj rekordy o identycznym ID filmu. Dzięki temu dynamika już opublikowanego materiału pozostaje oddzielona od wyników nowych publikacji.

Podłączanie TikTok Scraper API

W opisie TikTok Scraper API podano adres bazowy https://tiktok.evelode.com, a dokumentacja endpointów potwierdza GET /getUserFeed oraz parametry query, max_cursor, count, region, with_pinned_posts, sort_type i cache_timeout. Do pierwszego zapytania wystarczy wskazać profil w query i na przykład liczbę elementów za pomocą count. Klucz license_key przekazuje się w query stringu; jego konfigurację opisuje również dokumentacja API. W kolekcji Postman można sprawdzić endpoint i zweryfikować odpowiedź przed integracją.

Przechowuj klucz w zmiennej środowiskowej. Nie umieszczaj go w kodzie źródłowym, repozytorium, tabeli ani aplikacji klienckiej. Wykonaj zapytanie, zapisz udany przykład JSON wraz z datą i nazwą endpointu, a następnie wykorzystaj go jako podstawę adaptera normalizującego i testów.

Minimalne działające zapytanie w Pythonie

Dokumentacja wskazuje, że odpowiedź feedu użytkownika zawiera zewnętrzny status i obiekt tiktok, w którym lista publikacji znajduje się w aweme_list. Rekordy mogą zawierać ID, podpis, czas publikacji, autora i statystyki. Konkretne pola i wartości należy sprawdzić w otrzymanej odpowiedzi: niektórych danych może brakować.

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("Oczekiwano obiektu JSON")
    if payload.get("status") != "ok":
        raise RuntimeError(f"API zwróciło status: {payload.get('status')!r}")
    tiktok = payload.get("tiktok")
    if not isinstance(tiktok, dict):
        raise ValueError("W odpowiedzi brakuje obiektu tiktok")
    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("Pole tiktok.aweme_list nie jest listą")

    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"Zapisano: {raw_path}; liczba rekordów: {len(observations)}")

Przed uruchomieniem ustaw zmienną środowiskową JSONSCRAPER_TIKTOK_LICENSE_KEY i zainstaluj bibliotekę requests. Kod sprawdza odpowiedź HTTP, zewnętrzny status i obecność obiektu tiktok, a następnie odczytuje aweme_list. Zapisuje surowy JSON i pobiera pola potwierdzone w dokumentacji, pozostawiając brakujące wartości puste. Uzyskany feed to zestaw wyników zwrócony przez API, dlatego raport należy powiązać z czasem zapytania i wybranym profilem.

Przechowuj zrzuty i porównuj publikacje

W małym projekcie sprawdzą się SQLite lub PostgreSQL. Surową odpowiedź przechowuj oddzielnie od znormalizowanych rekordów. W tabeli obserwacji można zastosować następujący schemat:

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)
);

Każde uruchomienie dodaje nowy zrzut zamiast nadpisywać poprzedni. Przy porównywaniu liczników obliczaj różnicę tylko wtedy, gdy dostępne są obie wartości dla tego samego filmu. Uwzględnij w raporcie odstęp między zapytaniami i czas obserwacji: wyjaśniają one, w jakim okresie nastąpiła zmiana.

Grupowanie tematyczne zacznij od niewielkiego słownika kategorii, a w razie potrzeby dodaj klasyfikator lub model językowy. Przekazuj modelowi oczyszczone podpisy, ID publikacji i wcześniej ustalone kategorie. Ustrukturyzowany wynik z kategorią i krótkim uzasadnieniem łatwiej porównywać między uruchomieniami niż swobodny opis.

Dodaj model językowy i weryfikowalne etykiety

Model może wstępnie przypisywać podpisy do tematów, takich jak „przepisy”, „treningi”, „recenzje produktów” i „historie osobiste”. Na początek ręcznie oznacz kilkadziesiąt publikacji. Porównaj automatyczne etykiety z tymi przykładami, doprecyzuj definicje kategorii i ponownie oceń wyniki po zmianie promptu lub modelu.

Liczbę nowych publikacji, medianę liczników i różnicę między zrzutami lepiej obliczać zwykłym kodem. Model wykorzystuj do klasyfikacji tekstu i przygotowywania krótkich wyjaśnień. Zachowaj oryginalne podpisy i obserwacje liczbowe, aby można je było zweryfikować.

Wraz z etykietą zapisuj ID publikacji, wersję promptu, datę przetworzenia i użyty model. W przypadku błędnej klasyfikacji analityk będzie mógł odnaleźć podpis i poprawić regułę. Warto przechowywać osobno etykietę pierwotną i ręczną korektę.

Zautomatyzuj uruchamianie

Po sprawdzeniu ręcznego uruchomienia przenieś skrypt do cron, GitHub Actions, n8n lub Make. Harmonogram uruchamia pobieranie zgodnie z planem, przekazuje listę kont, rejestruje wynik i wysyła raport do wybranego magazynu danych. Klucz przechowuj w sekretach środowiska wykonawczego. Najpierw sprawdź proces na jednym koncie, a dopiero potem rozszerz listę.

Podziel automatyzację na etapy: kolejkę kont, wywołanie API, zapis surowej odpowiedzi, normalizację, zapis zrzutu i przygotowanie raportu. Błąd dotyczący jednego konta nie powinien usuwać wyników pozostałych. Ponowne uruchomienie można uczynić idempotentnym, stosując ID uruchomienia i ograniczenia unikalności w bazie.

Rejestruj czas, konto, endpoint, status HTTP, czas trwania, liczbę przetworzonych elementów i opis błędu. Nie zapisuj klucza API w logu. Parametr cache_timeout jest wymieniony dla /getUserFeed; można dodać go do zapytania, jeśli potrzebny jest określony czas przechowywania w pamięci podręcznej. W dokumentacji API wartość domyślna wynosi 3600 sekund.

Sprawdź jakość przed opublikowaniem raportu

Porównaj kilka znormalizowanych rekordów z surowym JSON-em. Sprawdź, czy ponowne pobranie rozpoznaje ten sam film po ID, daty są interpretowane zgodnie z oczekiwaniami, pola liczbowe mają właściwy typ, a udział brakujących danych jest znany. Następnie uruchom proces ponownie i upewnij się, że baza zachowała wcześniejsze obserwacje oraz dodała nowe.

Nie mieszaj kont i okresów pobierania. Do porównywania tematów używaj okresów o tej samej długości albo wyraźnie pokazuj ich długość w raporcie. Przy analizie dynamiki liczników podawaj odstęp między zrzutami, aby czytelnik rozumiał skalę porównywanych przedziałów.

Zachowuj oryginalny tekst podpisu i twórz osobno jego oczyszczoną wersję. Emoji, hashtagi, linki i cechy języka mogą wpływać na klasyfikację; osobne pola ułatwią sprawdzenie wpływu oczyszczania i ponowne obliczenie kategorii bez kolejnego wywołania API.

Jakie wyniki da pipeline

Po kilku cyklach zespół otrzyma tabelę publikacji i zrzutów, wstępne grupowanie podpisów według tematów oraz raport nowych filmów z wybranego okresu. Ułatwi to wybór materiałów do eksperckiego przeglądu, dostrzeżenie powtarzających się tematów na wybranych kontach i sprawdzenie zmian publicznych liczników między datami obserwacji.

Na podstawie tych danych można sformułować hipotezy do kalendarza redakcyjnego: porównać sposoby przedstawiania tego samego zagadnienia lub wybrać tematy do przetestowania we własnych treściach. Aby ocenić efekt komercyjny, zestaw obserwacje z wewnętrznymi danymi kampanii.

Na początek wybierz krótką listę publicznych kont i sprawdź GET /getUserFeed w kolekcji zapytań Postman. Do kodu przenoś wyłącznie parametry i ścieżki do pól potwierdzone w dokumentacji endpointu i jego rzeczywistej odpowiedzi.

Odpowiedzialne zbieranie danych publicznych

Ogranicz listę kont do celu badania, zbieraj tylko potrzebne pola i określ okres przechowywania surowych odpowiedzi. Przed komercyjnym wykorzystaniem danych sprawdź obowiązujące warunki platformy i wymogi dotyczące danych osobowych w swojej jurysdykcji. Kontrola dostępu i usuwanie nieaktualnych zrzutów pomagają utrzymać proces w granicach zadania.

Przed wysłaniem danych do usługi AI usuwaj pola, których model nie potrzebuje. W raporcie podawaj ID publikacji i datę obserwacji, aby pracownik mógł przejść do rekordu i zweryfikować podstawę wniosku.

Krótka lista kontrolna uruchomienia

  1. Określ niszę, listę kont, okres i pytania analityczne.
  2. Sprawdź parametry GET /getUserFeed w dokumentacji oraz rzeczywistą odpowiedź w Postmanie.
  3. Zapisz przykładowy JSON i skonfiguruj normalizator dla potwierdzonych pól.
  4. Zapisuj surową odpowiedź oraz osobne zrzuty wraz z czasem pobrania.
  5. Obliczaj wskaźniki liczbowe kodem; używaj AI do wstępnego grupowania tekstu.
  6. Dodaj harmonogram, logowanie, obsługę ponowień i okres przechowywania.

Dzięki temu monitoring staje się powtarzalnym badaniem: każdy wniosek jest powiązany z publikacją i czasem obserwacji, a kod opiera się na rzeczywistym schemacie wybranego endpointu.

Keep readingJak archiwizować wyniki wyszukiwania TikToka w Pythonie
Read the next article

Zmień lekturę w działającą integrację

Poznaj API danych społecznościowych jsonscraper, testuj zapytania i buduj kolejne procesy.

Poznaj API