Как создать телеграм-бота для анализа ранжирования карточек Wildberries

    В этой статье мы разберём, как с помощью публичных данных Wildberries (фронтовые JSON, autosuggest и SERP) построить телеграм-бота, который по артикулу nmId или ссылке показывает поисковые фразы, позицию в органике и факт рекламы. Решение не требует продавцких токенов и работает с троттлингом и кэшированием.

    Архитектура сбора данных: BFS и валидация

    Мы используем Node.js и TypeScript. Основной метод - BFS по подсказкам autosuggest с последующей нормализацией. Для каждой фразы выполняется валидация через SERP-страницы Wildberries по маршруту /exactmatch/…search?query=&page=. Парсинг включает поля products[*].id/name/brand и определение позиции целевого nmId. Для проверки рекламы вызывается https://catalog-ads.wildberries.ru/api/v5/search?keyword=.... Если nmId найден в рекламном блоке, карточка помечается ⚡. CPM часто равен null, поэтому используем эвристику.

    Троттлинг и кэширование

    Для соблюдения таймингов и избежания блокировок применяется библиотека Bottleneck (около 0.45 RPS на хост). Запросы обрабатываются с помощью axios-retry с экспоненциальной задержкой и джиттером. Redis с TTL-кэшем (для suggest, SERP, карточек и рекламы) ускоряет повторные запросы. Базовый скоринг позволяет отфильтровать наиболее релевантные фразы.

    Проблемы и гипотеза прединдекса

    Основные сложности - малое количество фраз по сравнению с конкурентами (они показывают в 3-4 раза больше) и долгое время первого ответа (ожидание BFS и валидации). Гипотеза: мгновенный ответ из индекса/кэша (OpenSearch с русским анализатором и shingle(2,3) плюс Redis Top-K), а глубокий сбор фраз выполнять в фоне. Это позволяет отдавать топ-5 позиций за секунды.

    Настройки OpenSearch/Elasticsearch для русского языка

    Для индексации фраз используйте комбинацию шинглов (shingle) и edge_ngram. Рекомендуем анализатор с морфологией (например, pymorphy2 или встроенный russian в OpenSearch). Пример маппинга:

    {
      "settings": {
        "analysis": {
          "filter": {
            "shingle_filter": {
              "type": "shingle",
              "min_shingle_size": 2,
              "max_shingle_size": 3
            },
            "edge_ngram_filter": {
              "type": "edge_ngram",
              "min_gram": 2,
              "max_gram": 10
            }
          },
          "analyzer": {
            "russian_shingle": {
              "tokenizer": "standard",
              "filter": ["lowercase", "stop", "russian_stemmer", "shingle_filter"]
            }
          }
        }
      }
    }

    Стоп-слова и нормализация обязательны. Для быстрого top-K используйте поле с type: "search_as_you_type" или отдельный индекс с агрегациями.

    Параметры SERP-валидации и парсинг версий

    Стабильно работают exactmatch-роуты из DevTools. Параметры: dest (регион), spp (страница), lang (язык), curr (валюта). Для толерантности к версиям (v18/v4) проверяйте структуру ответа - продукты могут быть в data.products или products. Используйте fallback-парсинг.

    Реклама: catalog-ads и эвристика CPM

    Факт рекламы подтверждается через /api/v5/search?keyword= - если nmId присутствует в ответе, карточка рекламируется. Поле CPM публично почти всегда null, поэтому полагайтесь на наличие/отсутствие id в блоке. Эвристика: если карточка в топ-3 и есть метка рекламы, считаем CPM высоким.

    Морфология: pymorphy2 или шинглы?

    Для продакшена под русский язык надёжнее использовать pymorphy2 в виде отдельного микросервиса (FastAPI). Он даёт корректную нормализацию словоформ. Однако, если требуется максимальная скорость, достаточно токенизации + шинглов (2-3 граммы) - это покрывает большинство запросов без потери качества.

    Антибот и скорость: RPS и прокси

    Оптимальный RPS - 0.3-0.5 на хост с экспоненциальным backoff. При соблюдении robots.txt и ToS пул IP/прокси не обязателен, но может увеличить «урожай» при массовом сборе. Используйте случайные задержки между запросами (джиттер).

    Архитектура очередей BullMQ

    Пайплайн: collect (BFS autosuggest) → verify (SERP-валидация) → rank (скоринг) → persist (сохранение в OpenSearch и Redis). Мгновенный ответ из кэша: топ-5 фраз с позициями. Фоновые задачи донаполняют индекс. Используйте отдельные очереди для сбора и валидации, чтобы не блокировать UI.

    FAQ по парсингу Wildberries

    Ниже собраны ответы на частые вопросы разработчиков.

    Часто задаваемые вопросы