Перейти к содержимому
PD
Автоматизация

Etsy Keyword Finder

Приложение для аудита ключевых слов Etsy на очереди задач: отправляете ID листинга и до 20 ключей, а фоновые воркеры проходят реальную выдачу шаг за шагом со скриншотами.

Проблема

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

Результат

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

Технологии

Next.jsTypeScriptPostgreSQLPlaywrightTailwind CSSNode.js-воркеры

Обзор

Etsy Keyword Finder - веб-приложение, которое превращает вопрос «на каком месте мой листинг по этому ключу?» в повторяемую фоновую задачу с полным протоколом. Продавец отправляет ID листинга и до 20 ключевых слов, выбирает поведение прогона и жмёт «Запустить». Дальше задача попадает в очередь, её арендует воркер и выполняет ключ за ключом - каждый шаг фиксируется скриншотом и строкой лога с временем, которые потом можно пересмотреть.

Интерфейс намеренно разделён надвое: сторона отправки (создать задачу, видеть последние прогоны) и сторона истории (искать, фильтровать и открывать любой прошлый прогон). Ничего из прогона не теряется - скриншоты и лог остаются привязаны к задаче.

Проблема

Ручная проверка видимости по ключам плоха сразу с трёх сторон. Она медленная - по одному ключу и по одной странице за раз. Она персонализирована: своя залогиненная сессия, гео и история поиска искажают выдачу, поэтому продавец видит не то, что видит новый посетитель. И она неповторяема - ничего не записывается, так что сравнить сегодняшнюю проверку с прошлой неделей или показать, что реально происходило, невозможно.

Умножьте это на двадцать ключей - и задача перестаёт выполняться регулярно вообще.

Решение

Каждая проверка описана как задача в очереди PostgreSQL. Дашборд валидирует и нормализует ввод заранее: ID листинга ограничен 6–20 цифрами, список ключей обрезается по пробелам и дедуплицируется без учёта регистра, а потолок в 20 ключей проверяется в интерфейсе до постановки в очередь. Воркеры забирают задачи через FOR UPDATE SKIP LOCKED, поэтому несколько узлов разбирают очередь параллельно и никогда не берут одну задачу дважды, а каждый захват - это аренда со 120-секундным heartbeat: если воркер умер посреди прогона, аренда истекает и задача возвращается в очередь, а не висит вечно.

Само выполнение не «чёрный ящик»: каждая стадия - сессия браузера, загрузка страницы, закрытие попапов, ввод запроса, капча, целевой листинг - пишет скриншот и запись в лог, так что страница задачи читается как бортовой самописец прогона.

Возможности

  • Форма постановки задачи со строгой валидацией: ID листинга 6–20 цифр, 1–20 ключей (2–80 символов), автотрим и дедупликация без учёта регистра
  • Настройки автоматизации на задачу: метод входа (случайный 1/2/3), случайные клики по листингам, регион прокси, необязательный реферер, переключатели «в корзину» и загрузки изображений
  • Очередь задач в PostgreSQL с захватом через FOR UPDATE SKIP LOCKED и арендой со 120-секундным heartbeat для восстановления после падений
  • Живой просмотр задачи: транслируемый скриншот браузера, галерея скриншотов по шагам и лог шагов с таймстампами
  • История задач с поиском по ID листинга и фильтрами по статусу - Все / В очереди / Выполняется / Завершено / Ошибка / Отменено
  • Прогресс-бары и бейджи статуса, агрегированные по всем ключам задачи
  • Блок последних задач на дашборде с переходом в любой прогон в один клик
  • Доступ по авторизации, задачи изолированы по аккаунту
  • Модульный адаптер воркера (ProcessAuthorizedJob): бэкенд выполнения можно подменить или замокать, не трогая слой приложения
  • Ограничение частоты отправки, чтобы объём запросов оставался умеренным и предсказуемым

Процесс разработки

Первой делалась очередь, потому что от её корректности под конкурентностью зависит всё остальное. SKIP LOCKED плюс аренда с heartbeat - это немного SQL, который убирает целый класс отказов: нет двойной обработки и нет задач, застрявших в running из-за перезагрузки VPS. И только когда захват и возврат в очередь стали надёжными, добавилась инструментация прогона - и именно она оказалась главной в ежедневном использовании, потому что аудит ключей, который нельзя проверить глазами, - это аудит, которому нельзя доверять.

Воркер спрятан за одним интерфейсом-адаптером: фронтенд разрабатывался против мока, пока настоящая автоматизация ещё донастраивалась, а дашборду и сейчас всё равно, как именно выполняется прогон.

Результаты

  • Аудит по двадцати ключам - это одна отправка формы вместо вечера ручных проверок
  • Каждый прогон воспроизводим и проверяем: скриншоты и лог шагов хранятся вместе с задачей
  • Несколько воркеров безопасно разбирают одну очередь - пропускная способность растёт добавлением узлов
  • Упавшие прогоны чинятся сами: аренда истекает, задача возвращается в очередь, а не теряется
  • История с поиском и фильтрами делает сравнение неделя к неделе привычкой, а не отдельной ручной работой

Выводы

Интересная инженерия здесь не в браузерной автоматизации, а в семантике очереди вокруг неё. Правильные захват, аренда и возврат задачи на уровне БД позволили остальной системе остаться простой: воркеры без состояния, приложение не отслеживает, кто чем занят, а масштабирование - это просто запуск ещё одного узла.

Второй вывод - про доверие. Скриншот на каждом шаге начинался как отладочный инструмент для меня, а стал самой ценной частью продукта для пользователя, потому что превращает утверждение автоматики в видимое доказательство. Та же логика, что и живая консоль в RPA Automation Panel: когда система действует за тебя, показывать свою работу - это функция, а не накладные расходы.

Услуги в этом проекте

Похожие кейсы

Нужна похожая система?

Расскажите о своей задаче - я предложу архитектуру и кратчайший путь к рабочему продукту.