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.

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
- Określ niszę, listę kont, okres i pytania analityczne.
- Sprawdź parametry
GET /getUserFeedw dokumentacji oraz rzeczywistą odpowiedź w Postmanie. - Zapisz przykładowy JSON i skonfiguruj normalizator dla potwierdzonych pól.
- Zapisuj surową odpowiedź oraz osobne zrzuty wraz z czasem pobrania.
- Obliczaj wskaźniki liczbowe kodem; używaj AI do wstępnego grupowania tekstu.
- 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.