Креатор може здаватися вдалим для кампанії за профілем і кількома успішними роликами, але його свіжа стрічка розповідає важливішу історію: чи продовжує він регулярно говорити на потрібну тему? Ручна перевірка швидко застаріває, а разовий перегляд легко зводиться до вибору найпомітніших публікацій. Агентству чи бренду корисніше зібрати повторювану вибірку публічних роликів, зберігати стан на дату перевірки й оцінювати тематичну відповідність за однаковими правилами.

Нижче наведено практичний процес оцінювання публічної стрічки TikTok-креатора. Він використовує TikTok Scraper API jsonscraper і Python: отримує публікації через задокументований маршрут, зберігає вихідний JSON, переносить підтверджені поля до таблиці й обчислює частку роликів, що відповідають заданій темі. За бажанням описи можна передати текстовому класифікатору як наступний, окремо контрольований етап.
Спочатку визначте, що означає «відповідає»
Припустімо, команда обирає автора для кампанії про приготування кави вдома. Кількість підписників і популярність окремих роликів можуть допомогти описати охоплення, але самі по собі не відповідають на запитання, наскільки стрічка пов’язана з кавою. Для першого відбору потрібні ознаки змісту: чи згадує опис ролика приготування кави, обладнання, рецепти або огляди; скільки публікацій на цю тему потрапило у визначене вікно спостереження; якою є частка тематичних роликів серед зібраних.
Перед збором даних запишіть критерії у короткий словник: наприклад, «еспресо», «кавомолка», «лате», «заварювання». Додайте винятки й неоднозначні слова. «Кава» може трапитися в жарті, рекламній інтеграції чи випадковому контексті, тому автоматичний збіг тексту — це первинне маркування, а не остаточна оцінка автора. Розрізняйте щонайменше три статуси: явна відповідність, можлива відповідність і нерелевантний ролик.
Вибірку теж потрібно визначити заздалегідь. Наприклад, можна аналізувати останні 20 отриманих публікацій під час кожного щотижневого запуску. Це умова вашого моніторингу, а не обіцянка API повернути саме такий обсяг: доступність і склад результатів визначаються відповіддю на конкретний запит. Записуйте час збору, кількість отриманих елементів і параметри запиту, щоб порівнювати знімки за однаковими правилами.
Запит до стрічки автора
У документації jsonscraper маршрут GET /getUserFeed приймає обов’язковий параметр query — ім’я користувача або URL профілю. Серед необов’язкових параметрів зазначені count, region, sort_type, with_pinned_posts і max_cursor. Ключ API передається як license_key у рядку запиту; зберігайте його у змінній середовища, а не у вихідному коді. Докладні відомості про маршрути й параметри наведені в офіційній документації TikTok API.
У відповіді спочатку перевірте зовнішній status, а потім звертайтеся до об’єкта tiktok. Для стрічки користувача список публікацій міститься в tiktok.aweme_list. У спостережуваній схемі є ідентифікатор ролика, текст опису, час публікації, автор, URL та об’єкт статистики. Окремі поля можуть бути відсутні, тому обробник має зберігати порожні значення як порожні, а не підставляти вигадані числа.
Наступний мінімальний приклад призначений для Python 3.8+ і бібліотеки requests. Збережіть ключ у JSONSCRAPER_TIKTOK_LICENSE_KEY. Код виконує один запит, перевіряє HTTP-відповідь і зовнішній статус API, записує вихідний JSON і виводить нормалізовані рядки.
import json
import os
from datetime import datetime, timezone
from pathlib import Path
import requests
API_KEY = os.environ["JSONSCRAPER_TIKTOK_LICENSE_KEY"]
PROFILE = "creator_username"
params = {
"license_key": API_KEY,
"query": PROFILE,
"count": 20,
"region": "US",
"sort_type": 0,
"with_pinned_posts": 0,
}
response = requests.get(
"https://tiktok.evelode.com/getUserFeed",
params=params,
timeout=30,
)
response.raise_for_status()
payload = response.json()
if payload.get("status") != "ok":
raise RuntimeError("TikTok API returned a non-ok status")
tiktok = payload.get("tiktok") or {}
items = tiktok.get("aweme_list") or []
stamp = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%SZ")
Path("snapshots").mkdir(exist_ok=True)
Path(f"snapshots/{PROFILE}_{stamp}.json").write_text(
json.dumps(payload, ensure_ascii=False, indent=2),
encoding="utf-8",
)
rows = []
for item in items:
stats = item.get("statistics") or {}
author = item.get("author") or {}
rows.append({
"aweme_id": item.get("aweme_id"),
"created_at": item.get("create_time"),
"description": item.get("desc") or "",
"share_url": item.get("share_url"),
"creator": author.get("unique_id") or author.get("nickname"),
"play_count": stats.get("play_count"),
"digg_count": stats.get("digg_count"),
"comment_count": stats.get("comment_count"),
"share_count": stats.get("share_count"),
})
print(json.dumps(rows, ensure_ascii=False, indent=2))
Параметр sort_type для цього маршруту описаний так: 0 — для стрічки останніх публікацій, 1 — для популярних. У прикладі вибрано режим останніх публікацій, а закріплені ролики виключені через with_pinned_posts=0, щоб старий закріплений допис не потрапляв до вибірки нових публікацій. Якщо потрібен інший режим, зберігайте параметр у метаданих знімка й застосовуйте його однаково під час кожного запуску.
Обробка відповіді: від JSON до відтворюваної таблиці
Корисно зберігати вихідну відповідь до будь-яких перетворень. Так можна перевірити нормалізацію, з’ясувати, чому рядок виявився порожнім, і адаптувати обробник, якщо у відповідях зміниться наявність необов’язкових полів. У робочому сховищі разом із JSON зберігайте час збору в UTC, профіль-запит, параметри й версію скрипту. Не додавайте ключ API до архіву чи журналу.
Для повторних запусків використовуйте aweme_id як ідентифікатор публікації, якщо поле наявне. Дедуплікація за цим ID не дасть зарахувати один ролик як кілька публікацій у разі повторного отримання. Водночас зберігайте окремі знімки статистики: значення переглядів і реакцій стосуються моменту спостереження, а не незмінних характеристик ролика. Якщо поле статистики відсутнє, залиште його порожнім і виключіть цей запис із розрахунку відповідної метрики.
Час публікації у схемі позначений як create_time. Для аналітичної таблиці перетворіть його на дату й зберігайте початкове значення разом із нормалізованим часом UTC. Перед розрахунками перевірте кілька реальних записів з отриманої відповіді, щоб упевнитися в очікуваному типі й одиницях вимірювання. Така перевірка особливо важлива для побудови часових графіків: помилка перетворення часу зміщує публікації між днями й спотворює порівняння тижнів.
Мінімальний тематичний класифікатор можна побудувати без моделі: нормалізувати текст, знаходити задані ключові фрази й позначати збіги. Для кориснішого маркування підготуйте набір вручну перевірених описів і правила для спірних випадків. Потім порівняйте простий словниковий фільтр із розміткою людини: з’ясуйте, які вирази дають хибні збіги, й оновіть словник. Це створює зрозумілий базовий рівень для оцінювання подальшого використання ШІ.
import re
KEYWORDS = (
"кофе", "эспрессо", "кофемолка", "латте", "заваривание",
)
def normalize(text):
text = (text or "").casefold()
return re.sub(r"\s+", " ", text).strip()
def classify(description):
text = normalize(description)
matches = [word for word in KEYWORDS if word in text]
return {
"topic_match": bool(matches),
"matched_terms": matches,
}
for row in rows:
row.update(classify(row["description"]))
Ключове слово в описі може бути корисним сигналом, але класифікатор має повертати зрозуміле пояснення — список збіглих термінів, а не лише мітку «так/ні». Для мовних моделей використовуйте структурований запит: передайте опис ролика й фіксовані категорії, попросіть повернути категорію, коротке обґрунтування та рівень упевненості. Зберігайте вихідний текст і відповідь моделі окремо. Рішення, що впливають на бюджет або вибір партнера, перевіряйте вручну за посиланнями на публікації.
Розраховуйте показники з чітким знаменником
Для простого звіту підійдуть частка тематичних роликів і частота публікацій. Частка дорівнює кількості роликів із підтвердженою тематичною відповідністю, поділеній на кількість роликів, які вдалося класифікувати. Завжди показуйте обидва числа: наприклад, «7 із 18 перевірених описів». Так результат зрозумілий, а також видно, коли відсоток розрахований на надто малій вибірці.
Частоту публікацій можна виразити кількістю отриманих роликів за фіксований період, наприклад за останні 30 днів. Межі періоду визначайте за часом збору й датами публікацій. За щотижневих знімків зберігайте результат кожного запуску, а не лише оновлений підсумковий рядок: так видно зміни тематики й активності. Не трактуйте кількість зібраних елементів як повний архів публікацій автора — аналізуйте фактично отриману вибірку й чітко зазначайте її правило.
Статистику переглядів, уподобань, коментарів і поширень зручно використовувати як контекст для кожного ролика. Порівнювати абсолютні значення слід обережно: давніша публікація могла довше накопичувати реакції. Для порівняння в межах одного автора фіксуйте час кожного збору й аналізуйте динаміку того самого ролика між знімками. Не називайте різницю між двома знімками «швидкістю зростання», якщо інтервал і доступність вимірювань не зафіксовані.
Корисний підсумковий запис для кожного профілю містить дату збору, вибрані параметри, кількість отриманих публікацій, кількість класифікованих описів, кількість тематичних збігів, список прикладів URL і коротку примітку про неоднозначні випадки. Така таблиця дає змогу співробітнику перевірити висновок, а іншому аналітику — повторити методику для наступного профілю.
Пагінація та розклад
Якщо для вибірки потрібна наступна сторінка, документація для стрічки профілю використовує max_cursor, отриманий із попередньої відповіді. Передавайте його без перетворень: курсор — непрозоре значення, яке потрібно зберегти й повернути API. Також перевірте has_more у відповіді, якщо плануєте запитувати продовження. Обмежте кількість сторінок або загальний бюджет запитів, щоб збір завершувався передбачувано.
cursor = None
all_items = []
max_pages = 3
for _ in range(max_pages):
page_params = dict(params)
if cursor is not None:
page_params["max_cursor"] = cursor
page_response = requests.get(
"https://tiktok.evelode.com/getUserFeed",
params=page_params,
timeout=30,
)
page_response.raise_for_status()
page_payload = page_response.json()
if page_payload.get("status") != "ok":
raise RuntimeError("TikTok API returned a non-ok status")
page = page_payload.get("tiktok") or {}
all_items.extend(page.get("aweme_list") or [])
if not page.get("has_more"):
break
cursor = page.get("max_cursor")
if cursor is None:
break
Періодичність запуску обирайте відповідно до завдання: для первинного оцінювання достатньо ручного запуску; для списку авторів щотижневий розклад може виявляти зміни без постійних запитів. Запуск можна налаштувати через cron, CI-завдання або оркестратор. Схема проста: отримати профілі з таблиці, виконати запити з обмеженням паралельності, записати знімки, перевірити частку успішних відповідей і надіслати зведення до робочої таблиці. Після тимчасової помилки повторюйте запит з обмеженою кількістю спроб і затримкою, а помилки авторизованих запитів зберігайте окремо для перевірки ключа й конфігурації.
Де доречний ШІ, а де потрібна перевірка
ШІ корисний для класифікації описів зі сленгом, кількома мовами або формулюваннями без точного ключового слова. Спочатку задайте закритий список категорій і попросіть модель використовувати лише текст опису. Потім оцініть якість на невеликій вибірці, розміченій вручну: порівняйте категорії моделі з рішеннями редактора, окремо розберіть помилки й неоднозначні випадки. До звіту краще включити частку збігів моделі з ручною розміткою та кількість перевірених прикладів, а не неінтерпретований загальний бал.
Не доручайте моделі завдання «обери найкращого автора» без критеріїв. Натомість розділіть процес на вимірювані ознаки: тематична частка, регулярність, приклади релевантних роликів і діапазон публічних реакцій. Модель може стисло підсумувати ці поля й указати посилання на підстави; остаточне рішення залишається за командою, яка враховує формат кампанії, аудиторію та домовленості з автором.
Якщо аналіз стосується рекламних інтеграцій, окремо перевіряйте розкриття відносин автора з брендом за самими публікаціями й застосовними вимогами. Посібник Федеральної торгової комісії США пояснює, що зв’язок із брендом потрібно чітко розкривати поруч із рекомендацією; водночас біографії профілю чи прихованої частини тексту може бути недостатньо для помітного повідомлення аудиторії. Дивіться рекомендації FTC для авторів соцмереж. Моніторинг публічних даних допомагає зібрати матеріали для перевірки, але оцінювання дотримання правил потребує контексту конкретного допису й кампанії.
Що буде на виході
Після налаштування пайплайна команда отримує датовані знімки публічної стрічки, таблицю публікацій з описами й доступними метриками, а також відтворюваний розрахунок тематичної частки. На їхній основі можна швидше відбирати профілі для подальшої перевірки, помічати зміну тем і документувати причини оцінювання. Метод залишається перевірним: вихідний JSON, параметри запиту, правила класифікації й посилання на ролики дають змогу простежити шлях від даних до висновку.
Для першого тесту запустіть скрипт на одному профілі, збережіть необроблену відповідь і вручну перевірте кілька класифікацій. Потім зафіксуйте словник тем, правила вибірки й формат звіту. Коли результат стане відтворюваним, додайте розклад і чергу профілів. Опис маршрутів і параметрів шукайте в документації API, а огляд продукту й доступні варіанти інтеграції — на сторінці TikTok Scraper API.
Практичний контрольний список перед запуском
- Запишіть тему кампанії, словник відповідностей і приклади спірних випадків.
- Зафіксуйте вікно вибірки, значення
count, сортування й налаштування закріплених публікацій. - Зберігайте вихідний JSON, дату збору й параметри окремо від секретного ключа.
- Використовуйте
aweme_idдля дедуплікації, якщо ідентифікатор наявний. - Розрізняйте відсутнє значення та нуль і не усереднюйте метрики без чіткої підстави.
- Показуйте розмір вибірки поруч із тематичною часткою та додавайте посилання на приклади.
- Перевіряйте класифікацію ШІ на ручній вибірці, перш ніж використовувати її для рішень щодо кампанії.
- Оновлюйте оцінку за розкладом і порівнюйте знімки, зібрані за однаковими правилами.