После запуска приложения или новой функции обратная связь быстро рассеивается по коротким видео. Маркетолог вручную находит несколько роликов, пересылает ссылки в чат, а аналитик позже не может понять, какие публикации уже учитывались и как менялись просмотры. Практичное решение — регулярно собирать результаты поиска по нескольким устойчивым запросам, сохранять исходные ответы и строить отчёт по подтверждённым полям.

В этом руководстве мы настроим такой сбор для конкретного случая: команда выпустила новую функцию и хочет еженедельно отслеживать публичные TikTok-видео, в описании которых встречаются название продукта, ключевая функция или типичная проблема пользователя. Это мониторинг найденной поисковой выборки: API возвращает результаты по запросу и параметрам, а не гарантированный перечень всех публикаций о запуске.
Сначала определите, какой сигнал нужен команде
Большое число просмотров само по себе плохо объясняет, что следует делать дальше. Команде полезнее знать, какие вопросы повторяются, какие сценарии люди демонстрируют и какие ролики получают заметные публичные реакции. Поэтому сначала сформулируйте несколько поисковых фраз и решите, какие поля попадут в отчёт.
Например, для запуска инструмента планирования публикаций можно проверить запросы «название продукта», «планировщик контента» и «как запланировать TikTok». Фразы должны отражать разные способы, которыми люди могут описывать одну тему. Запишите их вместе с датой запуска мониторинга и регионом, чтобы последующие выгрузки можно было сравнивать при одинаковых настройках.
Минимальная таблица может содержать время сбора, поисковую фразу, идентификатор видео, ссылку, описание, имя автора, идентификатор автора и доступные значения просмотров, отметок «нравится» и комментариев. TikTok Scraper API документирует для результатов поиска такие поля, как aweme_id, desc, share_url, сведения об авторе и часть статистики. Конкретное поле нужно проверять в каждом объекте: отдельные метрики могут отсутствовать.
Подключите документированный поиск
Для поиска видео используйте GET-маршрут /searchVideo на базовом адресе https://tiktok.evelode.com. Документация перечисляет обязательный параметр keyword и дополнительные count, cursor, date_posted, sort_by, region и cache_timeout. Допустимые значения фильтра даты включают this-week, а сортировки — relevance, most-liked и date-posted. Их назначение и имена сверяйте с справочником маршрутов TikTok API.
Лицензионный ключ передаётся как query-параметр license_key. В рабочем скрипте читайте его из переменной среды JSONSCRAPER_TIKTOK_LICENSE_KEY, не записывайте секрет в исходный код и не выводите его в журналы. Этот пример рассчитан на Python 3.8+ и использует пакет requests:
import os
import requests
BASE_URL = "https://tiktok.evelode.com"
API_KEY = os.environ["JSONSCRAPER_TIKTOK_LICENSE_KEY"]
def search_videos(keyword, cursor=None):
params = {
"license_key": API_KEY,
"keyword": keyword,
"count": 20,
"date_posted": "this-week",
"sort_by": "date-posted",
"region": "US",
}
if cursor is not None:
params["cursor"] = cursor
response = requests.get(
f"{BASE_URL}/searchVideo",
params=params,
timeout=30,
)
response.raise_for_status()
payload = response.json()
if payload.get("status") != "ok":
raise RuntimeError("TikTok API вернул статус, отличный от ok")
return payload["tiktok"]
result = search_videos("content planning app")
print("Найденные объекты:", len(result.get("aweme_list", [])))
Скрипт проверяет HTTP-ошибку и внешний статус ответа. Успешный HTTP-ответ сам по себе не гарантирует, что в поиске есть видео: при пустой выборке список может оказаться пустым. Для первого запуска полезно сохранить ответ целиком в защищённое хранилище, чтобы сопоставить реальные объекты с таблицей нормализованных полей.
Разберите оба варианта поискового ответа
У поисковой выдачи есть важная особенность структуры. Видео могут находиться непосредственно в tiktok.aweme_list, а могут приходить внутри tiktok.search_item_list[].aweme_info. Если обработчик читает только первый список, он способен пропустить результаты, присутствующие во втором варианте.
Добавьте небольшой нормализатор, который поддерживает обе структуры и спокойно пропускает элементы без вложенного объекта видео:
def extract_awemes(tiktok):
items = list(tiktok.get("aweme_list") or [])
for item in tiktok.get("search_item_list") or []:
aweme = item.get("aweme_info")
if aweme:
items.append(aweme)
return items
def normalize(aweme, keyword, collected_at):
author = aweme.get("author") or {}
stats = aweme.get("statistics") or {}
return {
"collected_at": collected_at,
"keyword": keyword,
"video_id": aweme.get("aweme_id"),
"posted_at": aweme.get("create_time"),
"description": aweme.get("desc"),
"share_url": aweme.get("share_url"),
"author_id": author.get("uid"),
"author_name": author.get("nickname"),
"views": stats.get("play_count"),
"likes": stats.get("digg_count"),
"comments": stats.get("comment_count"),
"shares": stats.get("share_count"),
}
Отсутствующее значение остаётся None. Не подменяйте его нулём: ноль означает измеренное значение, тогда как None сохраняет факт, что поле не пришло. Такая разница влияет на средние, доли и любые выводы для команды.
Сохраните историю, а не только текущий снимок
Чтобы видеть динамику, храните отдельные записи наблюдений. Идентификатор видео подходит для дедупликации публикаций, но не для удаления истории: повторное появление того же ролика при следующем сборе даёт новую точку наблюдения. Например, уникальный ключ таблицы наблюдений можно составить из video_id и collected_at, а ссылку и описание сохранять в записи для удобной проверки.
Минимальная схема в SQLite пригодится для прототипа:
import sqlite3
conn = sqlite3.connect("tiktok_observations.sqlite3")
conn.execute("""
CREATE TABLE IF NOT EXISTS observations (
video_id TEXT NOT NULL,
collected_at TEXT NOT NULL,
keyword TEXT NOT NULL,
posted_at INTEGER,
description TEXT,
share_url TEXT,
author_id TEXT,
author_name TEXT,
views INTEGER,
likes INTEGER,
comments INTEGER,
shares INTEGER,
PRIMARY KEY (video_id, collected_at, keyword)
)
""")
conn.commit()
На практике нормализуйте время сбора в UTC, сохраняйте исходный JSON отдельно и добавьте столбец версии схемы. Исходный ответ помогает перепроверить преобразование, когда структура новых объектов отличается от привычной. Для публикаций, которые обнаружились по нескольким запросам, храните совпавшие ключевые фразы отдельной связанной таблицей или объединяйте их при построении отчёта.
Пагинация: продолжайте только по курсору из ответа
Параметр cursor предназначен для продолжения поиска. Его значение берётся из предыдущего ответа, передаётся обратно без преобразования, а работа завершается, когда has_more больше не сообщает о продолжении или когда достигнут заданный лимит. Курсор следует считать непрозрачным: не вычисляйте его самостоятельно и не заменяйте счётчиком страниц.
def collect_pages(keyword, max_pages=3):
cursor = None
collected = []
for _ in range(max_pages):
page = search_videos(keyword, cursor)
collected.extend(extract_awemes(page))
if not page.get("has_more"):
break
cursor = page.get("cursor")
if cursor is None:
break
return collected
Ограничение числа страниц делает регулярную задачу предсказуемой по объёму запросов. Записывайте число страниц и значение has_more в журнал выполнения: это даёт контекст для отчёта о выборке. Даже при пагинации результат описывает полученные ответы API и заданный лимит сбора; он не служит оценкой всех публикаций на платформе.
Соберите повторяемый отчёт
Запускайте сбор по расписанию раз в неделю или чаще, если команде нужны более частые сигналы. Для каждого запуска фиксируйте список запросов, параметры, время, число полученных объектов и число уникальных идентификаторов. Отдельно считайте публикации, впервые замеченные в этом запуске, и публикации, которые уже встречались ранее.
В отчёте полезны четыре простых представления:
- Новые видео: ссылки, описания, дата публикации и поисковая фраза, по которой ролик найден.
- Повторяющиеся темы: группировка описаний по вручную заданным категориям, например «ошибка настройки», «запрос функции» и «обзор сценария».
- Публичные реакции: доступные просмотры, лайки, комментарии и репосты, показанные рядом с временем наблюдения.
- Сигналы для проверки: новые формулировки, частые вопросы или ролики, которые стоит изучить сотруднику.
Не называйте разницу между двумя снимками «новыми лайками» без проверки семантики и свежести значений в ответе. Корректная формулировка — «значение метрики в последнем полученном ответе» и «разница между сохранёнными снимками». Так команда видит, что именно рассчитано, и может открыть исходную публикацию перед принятием решения.
Добавьте ИИ на этап классификации, а не вместо сбора
После нормализации можно передать описания видео модели для классификации по заранее определённым категориям. Отправляйте только необходимые текстовые поля и просите вернуть структурированный результат: категорию, краткое основание, уровень уверенности и фрагмент описания, на котором основана метка. Храните исходную публикацию рядом с меткой, чтобы аналитик мог проверить спорные случаи.
Рабочая схема остаётся простой: планировщик запускает сбор; Python проверяет ответ и сохраняет JSON; отдельная задача нормализует новые записи; классификатор обрабатывает только новые описания; отчёт строится из базы и отправляется в выбранный командой канал. Сам TikTok Scraper API предоставляет данные поиска, а классификация и доставка отчёта — ваша интеграционная логика, которую можно реализовать в Python, n8n или Make.
Чтобы снизить шум, задайте словарь категорий до отправки в модель и периодически проверяйте размеченную вручную выборку. Для коротких или неоднозначных описаний полезен статус «недостаточно контекста», а не принудительный выбор категории. Метки ИИ помогают сортировать очередь на просмотр, тогда как выводы о пользовательской проблеме подтверждайте чтением публикаций и сопоставлением нескольких наблюдений.
Ошибки, повторы и безопасное обращение с ключом
Сетевой запрос может завершиться тайм-аутом, временной ошибкой или ответом, который не удалось разобрать как JSON. Разделите обработку на этапы: запрос, проверка HTTP-кода, разбор JSON, проверка внешнего статуса, нормализация и запись. При временных сбоях используйте ограниченное число повторов с увеличивающейся паузой; постоянные ошибки записывайте для последующего разбора, не помечая запуск как успешный.
Ключ храните в менеджере секретов среды выполнения или переменной окружения. Поскольку API принимает license_key в строке запроса, избегайте журналирования полного URL и параметров запроса: в них окажется секрет. Для диагностики записывайте маршрут, код ответа, длительность, поисковую фразу и идентификатор задания, удаляя ключ из журналов.
Устанавливайте расписание и объём выборки согласно своей задаче и условиям использования платформы. Сбор публичных данных стоит ограничить тем, что действительно нужно для анализа; хранение описаний, ссылок и авторских идентификаторов следует описать во внутренних правилах команды. API-ответы и метрики могут быть неполными или изменяться между наблюдениями, поэтому отчёт должен сохранять время сбора и происхождение каждой строки.
Результат: от ручных ссылок к проверяемой истории
После настройки команда получает регулярно обновляемый список найденных роликов, исходные ответы для аудита, таблицу доступных публичных метрик и обзор повторяющихся тем. Это помогает быстрее замечать вопросы к новой функции, находить примеры пользовательских сценариев и выбирать публикации для ручного анализа. Сравнение снимков показывает, как меняются сохранённые значения у уже найденных роликов, а журнал запросов объясняет, каким способом сформировалась выборка.
Начните с одного запроса и небольшого лимита страниц, проверьте реальную структуру ответа, затем добавьте дополнительные формулировки и расписание. Перед переносом прототипа в производственную среду задайте правила дедупликации, хранения и обработки ошибок. Актуальные маршруты и параметры доступны в официальной документации API; описание возможностей и переход к тестированию — на странице TikTok Scraper API.