Мониторинг маркетплейсов без платных сервисов аналитики

Конкуренты, свои продажи, позиции и алерты по Wildberries и Ozon. Python stdlib, SQLite, Telegram-бот и разбор от LLM.

WB-монитор: главный экран

Что внутри

Один цикл раз в три часа: сбор, аналитика, алерты, дашборд, выгрузка на сайт. Ни одной pip-зависимости.

12,6

заказов на один отзыв

Коэффициент оценки продаж конкурентов калибруется автоматически по своим магазинам через API продавца.

Разбор ИИ каждое утро

Главное за период, события и что сделать, с ответственными.

Позиции в поиске

Топ-200 по своим запросам, доля рекламы, «кто выше нас», динамика за неделю.

Алерты с рекомендацией

Цена, остаток, демпинг, новый конкурент. Уровень важности и что делать.

Telegram-бот

Меню по площадкам, свободные вопросы к данным, доступ по заявке.

Как устроено

Весь код на Python 3.14 из стандартной библиотеки. Хранилище: один файл SQLite, резервная копия равна копии файла.

flowchart LR
  L[launchd, каждые 3 ч] --> C[app.collect<br/>card.wb.ru · basket · feedbacks · search]
  L --> S[app.wb_seller<br/>API продавца WB]
  L --> O[app.ozon<br/>Seller + Performance API]
  L --> M[app.sellmonitor<br/>MCP JSON-RPC]
  C --> DB[(SQLite<br/>wbmon.db)]
  S --> DB
  O --> DB
  M --> DB
  DB --> A[app.analyze<br/>метрики · калибровка · алерты]
  A --> LLM[LLM-разбор<br/>Codex CLI]
  A --> D[app.dashboard<br/>index.html + data.json]
  D --> W[sync.sh<br/>rsync / FTPS → сайт]
  A --> B[app.bot<br/>Telegram]
  LLM --> B
Python stdlibSQLiteWB APIOzon APITelegram Bot APIChart.jslaunchd

Экраны

Настоящие данные; названия компаний и брендов заменены.

Что было сложного

Продажи конкурентов, которых WB не отдаёт

Прирост отзывов на карточку умножается на коэффициент, который монитор сам измеряет по своим магазинам через API продавца.

search.wb.ru режет по IP

После десяти быстрых запросов 429 на минуты. Сборщик держит паузу 25 секунд и не снимает больше 30 ключей за цикл.

launchd и TCC на macOS

Shell из launchd не пускают в Documents, а Python из /Library/Frameworks пускают. Поэтому цикл написан на Python.

Хостинг банит SSH с IP VPN

Транспорт FTPS с переиспользованием TLS-сессии на канале данных, иначе vsftpd отвечает 522.