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

В этом руководстве показан архивный пайплайн на Python для сохранения результатов поиска по фиксированным фразам. В отличие от мониторинга отдельных хэштегов или аккаунтов, здесь ключ к сравнению — повторять одни и те же поисковые фразы и сохранять отдельный снимок каждого ответа. Страница TikTok Scraper API jsonscraper указывает базовый адрес и маршрут GET /searchVideo; в документации этого маршрута поисковая фраза передаётся в обязательном параметре keyword.
Задача и границы измерения
Представим, что маркетолог хочет каждый день собирать выдачу по нескольким фиксированным фразам: названию продукта, категории и формулировке проблемы клиента. Для каждого запроса система сохраняет время сбора и ответ API. После проверки примера ответа можно добавить нормализацию полей, которые действительно присутствуют в JSON, например идентификатора видео или публичных счётчиков, если они там есть.
Архив отвечает на конкретный вопрос: какие записи вернул поиск по сохранённой фразе во время этого запуска? Если ответ содержит метрики, повторные наблюдения могут показать разницу между значениями, зафиксированными в разные моменты. Такая разница относится к наблюдаемым снимкам и интервалу между ними; для сопоставления сохраняйте оба времени сбора и одно и то же поле.
Сохраняйте запрос вместе с ответом. Состав результатов относится к конкретной поисковой фразе и моменту сбора. Поэтому архив полезен для отслеживания выдачи по выбранным запросам, а не как полный обзор всего контента TikTok. Идентификаторы, исходные ответы и временные метки помогают проверить, откуда взялась каждая строка последующей таблицы.
Проверьте маршрут и его параметры
В карте маршрутов TikTok API указаны базовый адрес https://tiktok.evelode.com и GET /searchVideo. Актуальная спецификация API называет keyword обязательным параметром поиска; среди необязательных параметров перечислены cursor, count, cache_timeout, date_posted, sort_by и region. Для авторизации передаётся license_key. Сведения о маршруте также доступны в документации Python SDK.
Параметры count и date_posted помогают задать размер ответа и временной фильтр; sort_by принимает документированные значения most-liked, relevance или date-posted. Если используете пагинацию, передавайте полученный в предыдущем ответе cursor как непрозрачное значение, не вычисляя его самостоятельно. Для сравнимого дневного архива сохраняйте параметры запроса и версию собственного кода рядом с данными.
В примере ниже используется малое значение count для тестового запуска и фиксированный регион US. Перед ежедневным сбором проверьте один запрос, его HTTP-статус и структуру JSON. Схема ответа может содержать найденные ролики в tiktok.aweme_list или в tiktok.search_item_list, где объект видео расположен в aweme_info; код поддерживает обе наблюдавшиеся формы.
Подготовьте проект
Создайте виртуальное окружение и установите requests:
python -m venv .venv
source .venv/bin/activate
pip install requests
В PowerShell активация окружения выполняется командой .venv\Scripts\Activate.ps1. Задайте ключ и список поисковых фраз через переменные окружения. Для TikTok API используйте документированное имя переменной JSONSCRAPER_TIKTOK_LICENSE_KEY:
export JSONSCRAPER_TIKTOK_LICENSE_KEY="ваш_ключ"
export TIKTOK_QUERIES="название продукта,категория товара,проблема клиента"
Сбор и сохранение снимков
Пример отправляет по одному запросу на каждую фразу к документированному маршруту, затем сохраняет исходный JSON, время сбора и использованные параметры. В имени файла указывается дата и поисковая фраза. Ключ хранится в окружении и в архив не включается.
import json
import os
import re
import time
from datetime import datetime, timezone
from pathlib import Path
import requests
BASE_URL = "https://tiktok.evelode.com"
ENDPOINT = "/searchVideo"
LICENSE_KEY = os.environ["JSONSCRAPER_TIKTOK_LICENSE_KEY"]
QUERIES = [
item.strip()
for item in os.environ["TIKTOK_QUERIES"].split(",")
if item.strip()
]
OUT = Path("data")
OUT.mkdir(exist_ok=True)
def safe_name(text):
cleaned = re.sub(r"[^a-zA-Z0-9_-]+", "_", text).strip("_")
return cleaned[:80] or "query"
def fetch(query):
params = {
"license_key": LICENSE_KEY,
"keyword": query,
"count": 10,
"region": "US",
}
response = requests.get(
BASE_URL + ENDPOINT,
params=params,
timeout=60,
)
response.raise_for_status()
payload = response.json()
if payload.get("status") != "ok":
raise RuntimeError("API вернул статус, отличный от ok")
return payload
def extract_videos(payload):
tiktok = payload.get("tiktok") or {}
videos = list(tiktok.get("aweme_list") or [])
for item in tiktok.get("search_item_list") or []:
video = item.get("aweme_info") or {}
if video:
videos.append(video)
return videos
for query in QUERIES:
collected_at = datetime.now(timezone.utc).isoformat()
payload = fetch(query)
record = {
"collected_at": collected_at,
"query": query,
"request": {
"endpoint": ENDPOINT,
"keyword": query,
"count": 10,
"region": "US",
},
"videos_found": len(extract_videos(payload)),
"payload": payload,
}
filename = OUT / f"{collected_at[:10]}_{safe_name(query)}.json"
filename.write_text(
json.dumps(record, ensure_ascii=False, indent=2),
encoding="utf-8",
)
print(f"Сохранён ответ для запроса: {query}")
time.sleep(1)
print(f"Сохранено ответов: {len(QUERIES)}")
Этот минимальный сборщик делает один запрос на фразу с count=10. Для более широкого сбора добавьте пагинацию по cursor: продолжайте запросы, передавая значение курсора из ответа, пока API указывает, что есть следующие результаты, и фиксируйте каждый ответ отдельно. Курсор и число результатов определяют конкретный проход; сохранённый JSON позволяет позднее проверить, что именно вернулось в каждом запросе.
Пример проверяет внешний status, затем читает объект tiktok. Он собирает элементы из aweme_list, а также из search_item_list[].aweme_info, если эта форма присутствует. Возможные поля видеозаписи включают идентификатор, описание, автора, ссылку и статистику; отдельные поля могут отсутствовать. Поэтому сохраняйте полный ответ, а при нормализации проверяйте наличие каждого поля.
Интервал в одну секунду — пауза между запросами самого скрипта, а не заявление о лимитах сервиса. Частоту и повторы настройте с учётом условий доступа и документации. Параметр cache_timeout документирован для поиска; он позволяет задать срок кэширования в секундах, а значение 0 отключает кэширование согласно спецификации. Добавляйте его в запрос, когда такое поведение подходит вашему сценарию.
Добавьте нормализацию по фактическому ответу
После первого запуска откройте сохранённый файл и изучите структуру payload. Функция extract_videos в примере собирает элементы из двух документированных для ответа форм поиска мест. Найдите точные ключи полей, которые нужны для анализа. Если поле отсутствует в конкретной записи, сохраняйте его как отсутствующее значение, а не подставляйте предполагаемое число.
Для дальнейшей обработки удобно сформировать одну строку на каждый найденный объект, добавив к нему collected_at и query. Подтверждённые поля можно сохранять в CSV или базе данных, а исходный JSON оставить в архиве. Такая пара позволяет строить удобные таблицы и при этом проверять происхождение каждой записи.
Если API возвращает идентификатор ролика, используйте его для связывания наблюдений одного видео в разных запусках. Храните каждое наблюдение отдельно, не перезаписывая прошлое. При отсутствии устойчивого идентификатора сначала проверьте, какие атрибуты позволяют сопоставлять записи, и не считайте совпадение по тексту описания гарантированным.
Сравните снимки и подготовьте отчёт
После нормализации сгруппируйте записи по проверенному идентификатору и отсортируйте по времени сбора. Для полей-счётчиков разность двух последовательных значений можно вычислить обычным кодом. Например, переход с 12 400 до 18 900 означает, что между этими снимками значение счётчика изменилось на 6 500. В отчёте укажите даты наблюдений и исходное поле, чтобы читатель мог проверить расчёт.
Полезная структура итоговой таблицы включает фразу поиска, идентификатор публикации, время сбора и выбранные поля из ответа. Сводку можно сгруппировать по запросам и отсортировать по одному подтверждённому счётчику. Это даст команде проверяемый список возвращённых записей для дальнейшего просмотра; таблицу или сообщение реализуйте отдельным шагом после изучения фактической схемы.
Сначала храните файлы JSON локально. Когда сбор станет регулярным, перенесите нормализованные строки в PostgreSQL или аналитическое хранилище, а исходные ответы — в объектное хранилище с датой и запросом в имени. Сохранение исходника особенно полезно, когда вы уточняете парсер: его можно повторно запустить на исторических данных без повторного обращения к API.
Запускайте сбор по расписанию
Для ежедневного архива вызывайте скрипт через cron или другой планировщик, доступный в вашей среде. Например, задание может запускать Python-файл раз в сутки, передавая ему ключ и поисковые фразы через переменные окружения. Перед регулярным использованием проверьте один запрос, затем весь список и только после этого подключайте расписание.
Для надёжного запуска сохраняйте статус каждого запроса, ограничивайте число повторов при временных ошибках и отмечайте неполный сбор, если одна фраза завершилась неудачно. Не включайте ключ в сообщения об ошибках. Полезно также разделять файлы по дате и имени запроса, чтобы повторный запуск не перезаписывал предыдущий снимок.
Выбирайте частоту по задаче и объёму запросов. Для ежедневного обзора достаточно одного запуска в день; более частый сбор имеет смысл, когда команде важны изменения в течение дня. Начните с небольшого списка фраз, проверьте полезность возвращаемых результатов и затем расширяйте сбор в пределах условий доступа и правил использования данных.
Используйте ИИ для тематической группировки
Когда схема ответа подтверждена, выбранные текстовые поля можно передавать модели для группировки описаний по заранее заданным темам или подготовки краткого черновика сводки. Сохраняйте рядом с классификацией исходный идентификатор публикации, поисковую фразу и фрагмент текста, на котором основана категория. Так аналитик сможет перейти от вывода модели к исходной записи.
Числовые разности, сортировку и дедупликацию рассчитывайте обычным кодом. Модель пригодна для обработки текста и составления формулировок отчёта, а счётчики и временные метки берите из сохранённых ответов. Разделение этих операций делает происхождение каждого вывода понятным.
Проверяйте часть автоматических категорий вручную и сохраняйте исправления как тестовые примеры. Если разные типы публикаций регулярно попадают в одну группу, уточните определения категорий и повторите проверку. Такой процесс помогает оценивать качество классификации на данных вашей задачи.
Итог: повторяемый архив и проверяемая сводка
После запуска документированного запроса с параметром keyword у команды появляется архив: какие фразы запускались, когда это происходило и какие данные API вернул для каждой из них. На его основе можно построить таблицу результатов, сравнить подтверждённые поля между снимками и подготовить список найденных публикаций для ручного анализа.
Начните с одного тестового запроса, затем настройте список фраз и расписание. В описании TikTok Scraper API приведены базовый адрес и карта маршрутов; параметры /searchVideo и форма ответа описаны в спецификации API. Архивирование проверенных ответов создаёт основу для повторяемой аналитики по фиксированным поисковым фразам.