Etsy Keyword Finder
Приложение для аудита ключевых слов Etsy на очереди задач: отправляете ID листинга и до 20 ключей, а фоновые воркеры проходят реальную выдачу шаг за шагом со скриншотами.
Проблема
У продавца нет надёжного способа увидеть, где реально показывается его листинг по конкретному ключу: ручная проверка медленная, персонализирована его же сессией и не повторяется одинаково на десятках запросов.
Результат
Дашборд, раздающий задачи аудита арендованным фоновым воркерам: 20 ключей на задачу, скриншот на каждом шаге, живой лог шагов и история задач с поиском и фильтрами по статусу.
Технологии
Обзор
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: когда система действует за тебя, показывать свою работу - это функция, а не накладные расходы.
Услуги в этом проекте
Похожие кейсы
- LeadGen Outreach - система поиска клиентов на фриланс-биржахМоя собственная CRM с AI-движком: 14 источников заказов, отбор задач, отклики в лимиты площадок, воронка до предоплаты, AI-черновики ответов и анализ спроса по 5 811 задачам.
- Telegram-бот воронки продаж для онлайн-курсовTelegram-бот, который ведёт всю воронку - лид-магнит → гайд → интенсив → курс - с оплатой, автовыдачей доступа и админ-панелью.