Перейти к основному содержимому

Ключ к поиску — SEO-gap анализ vs конкуренты

Как найти ключевые слова, по которым конкуренты получают трафик, а клиент — нет. SEO на маркетплейсах отличается от Google: здесь нужны данные именно площадки, а не внешние инструменты.

Проблема

Селлеры на Wildberries составляют заголовки и описания карточек интуитивно. Типичная ситуация:

  • Копируют друг у друга — берут заголовок конкурента и слегка переставляют слова
  • Пишут «из головы» — используют термины, которые сами считают правильными, но покупатели ищут иначе
  • Игнорируют длинный хвост — фокусируются на 3-5 очевидных ключевых словах, упуская десятки низкоконкурентных запросов
  • Не анализируют конкурентов системно — не знают, по каким запросам ТОП-3 получают трафик

Результат: потерянный трафик, низкие позиции в поиске, деньги на рекламу вместо органики.

SEO на WB - это НЕ SEO в Google

На Wildberries поисковая оптимизация работает принципиально иначе:

  • Нет мета-тегов — алгоритм WB индексирует заголовок, описание, характеристики и текст на инфографике
  • Позиции меняются ежедневно — нельзя один раз оптимизировать и забыть
  • Реклама влияет на органику — рекламные позиции и органические считаются отдельно
  • Единственный источник правды — данные самого маркетплейса, а не Wordstat или Google Trends

MPStats собирает позиции товаров по каждому ключевому слову ежедневно — это основа для SEO-gap анализа.

Пайплайн данных

Ключевой эндпоинт MPStats

Формат данных API

Эндпоинт GET /wb/get/item/{sku}/by_keywords возвращает словарь ключевых слов с массивами позиций — по одному значению на каждый день за последние 30 дней. Это позволяет видеть не просто «товар ранжируется по запросу», а динамику позиций: рост, падение, стабильность.

Формат ответа:

{
"words": {
"ароматизатор": {
"pos": [2, 3, 3, 5, 4, 3, 2, ...],
"organic_pos": [0, 0, 1, 2, 1, 0, ...]
},
"пахучка": {
"pos": [1, 1, 2, 1, 1, 2, 1, ...],
"organic_pos": [1, 1, 1, 1, 1, 1, ...]
}
}
}
  • pos — общая позиция (реклама + органика)
  • organic_pos — чисто органическая позиция (без рекламы)
  • 0 означает «товар не найден по этому запросу в этот день»

Пайплайн SEO-gap анализа

graph LR
A["SKU клиента<br/>by_keywords"] --> D["Множество<br/>ключевых слов<br/>клиента"]
B["SKU конкурента 1<br/>by_keywords"] --> E["Множество<br/>ключевых слов<br/>конкурентов"]
C["SKU конкурента 2-3<br/>by_keywords"] --> E
D --> F["Сравнение:<br/>Gap = Конкуренты − Клиент"]
E --> F
F --> G["Приоритизация<br/>по позициям<br/>и частотности"]
G --> H["SEO-рекомендации<br/>+ новый заголовок"]

Логика пайплайна:

  1. Собрать ключевые слова клиента — запрос by_keywords для SKU клиента
  2. Собрать ключевые слова ТОП-3 конкурентов — те же запросы для конкурентных SKU (из лидеров категории)
  3. Вычислить SEO-gap — ключевые слова, по которым ранжируются конкуренты, но НЕ клиент
  4. Приоритизировать — выше приоритет у слов, где конкуренты в ТОП-10
  5. Сформировать рекомендации — какие слова добавить в заголовок, описание, инфографику

Анализ

Шаг 1. Получение ключевых слов SKU

import httpx
from collections import defaultdict

MPSTATS_TOKEN = "your_token"
BASE_URL = "https://mpstats.io/api"

def fetch_sku_keywords(sku: int) -> dict[str, dict]:
"""
Получить все ключевые слова SKU с позициями за 30 дней.
Возвращает: {"слово": {"pos": [...], "organic_pos": [...]}, ...}
"""
resp = httpx.get(
f"{BASE_URL}/wb/get/item/{sku}/by_keywords",
headers={"X-Mpstats-TOKEN": MPSTATS_TOKEN},
)
data = resp.json()
return data.get("words", {})

Шаг 2. Расчёт средней позиции

def avg_position(positions: list[int]) -> float | None:
"""
Средняя позиция за период, исключая нули (дни без ранжирования).
None означает, что товар вообще не появлялся по этому запросу.
"""
active = [p for p in positions if p > 0]
if not active:
return None
return sum(active) / len(active)


def build_keyword_profile(sku: int) -> dict[str, float]:
"""
Профиль ключевых слов SKU: {слово: средняя_позиция}.
Только слова, по которым товар реально ранжируется.
"""
keywords = fetch_sku_keywords(sku)
profile = {}
for word, data in keywords.items():
avg_pos = avg_position(data.get("pos", []))
if avg_pos is not None:
profile[word] = avg_pos
return profile

Шаг 3. SEO-gap анализ

def seo_gap_analysis(
client_sku: int,
competitor_skus: list[int],
) -> list[dict]:
"""
Найти ключевые слова, по которым ранжируются конкуренты,
но НЕ ранжируется клиент.

Возвращает список gap-слов с позициями каждого конкурента.
"""
# Профиль клиента
client_profile = build_keyword_profile(client_sku)
client_keywords = set(client_profile.keys())

# Профили конкурентов
competitor_profiles = {}
all_competitor_keywords = set()
for sku in competitor_skus:
profile = build_keyword_profile(sku)
competitor_profiles[sku] = profile
all_competitor_keywords.update(profile.keys())

# SEO-gap: слова конкурентов минус слова клиента
gap_keywords = all_competitor_keywords - client_keywords

# Собираем данные по каждому gap-слову
gap_analysis = []
for keyword in gap_keywords:
entry = {
"keyword": keyword,
"competitors": {},
"competitor_count": 0,
"best_competitor_pos": 999,
}
for sku in competitor_skus:
pos = competitor_profiles[sku].get(keyword)
if pos is not None:
entry["competitors"][sku] = round(pos, 1)
entry["competitor_count"] += 1
entry["best_competitor_pos"] = min(
entry["best_competitor_pos"], pos
)

gap_analysis.append(entry)

# Приоритизация: сначала слова, где больше конкурентов в топе
gap_analysis.sort(
key=lambda x: (-x["competitor_count"], x["best_competitor_pos"])
)

return gap_analysis


def classify_priority(entry: dict) -> str:
"""Классификация приоритета gap-слова."""
if entry["competitor_count"] >= 3 and entry["best_competitor_pos"] <= 10:
return "high" # Все конкуренты в ТОП-10 — критически важное слово
elif entry["competitor_count"] >= 2 and entry["best_competitor_pos"] <= 20:
return "high"
elif entry["competitor_count"] >= 2:
return "medium"
else:
return "low"

Шаг 4. Анализ «слабых позиций» клиента

def weak_positions_analysis(
client_sku: int,
competitor_skus: list[int],
threshold: int = 30,
) -> list[dict]:
"""
Слова, по которым клиент ранжируется, но ХУЖЕ конкурентов.
threshold — максимальная разница позиций для включения в отчёт.
"""
client_profile = build_keyword_profile(client_sku)
competitor_profiles = {
sku: build_keyword_profile(sku) for sku in competitor_skus
}

weak = []
for keyword, client_pos in client_profile.items():
best_comp_pos = 999
best_comp_sku = None
for sku, profile in competitor_profiles.items():
comp_pos = profile.get(keyword)
if comp_pos is not None and comp_pos < best_comp_pos:
best_comp_pos = comp_pos
best_comp_sku = sku

if best_comp_pos < client_pos and (client_pos - best_comp_pos) > 5:
weak.append({
"keyword": keyword,
"client_pos": round(client_pos, 1),
"best_competitor_pos": round(best_comp_pos, 1),
"gap": round(client_pos - best_comp_pos, 1),
"best_competitor_sku": best_comp_sku,
})

weak.sort(key=lambda x: -x["gap"])
return weak

Пример результата SEO-gap

Ключевое словоКонкурент 1Конкурент 2Конкурент 3КлиентПриоритет
ароматизатор для авто#3#7#12--🔴 Высокий
автопарфюм#1#4#8--🔴 Высокий
запах в машину#5#11#6--🔴 Высокий
пахучка автомобильная#2--#9--🔴 Высокий
освежитель воздуха машина#15#5#22#45:yellow_circle: Средний
ароматизатор подвесной#8--#14#38:yellow_circle: Средний
ёлочка в машину--#3---- Низкий

Интерпретация таблицы:

  • 🔴 Высокий приоритет — слово, по которому 2-3 конкурента в ТОП-10, а клиент отсутствует. Это прямая потеря трафика.
  • :yellow_circle: Средний приоритет — клиент ранжируется, но значительно хуже конкурентов. Оптимизация может поднять позиции.
  • Низкий приоритет — только один конкурент ранжируется. Слово может быть нишевым или случайным.

Пример «слабых позиций»

Ключевое словоКлиентЛучший конкурентРазницаДействие
освежитель воздуха машина#45#5-40 позицийДобавить в заголовок
ароматизатор подвесной#38#8-30 позицийДобавить в описание
запах для авто приятный#52#15-37 позицийИнфографика

Действие Fotofactor

1. SEO-оптимизация заголовка и описания

На основе gap-анализа Fotofactor переписывает карточку клиента:

Стратегия интеграции ключевых слов

Заголовок (title) — максимально ёмкий, содержит топ-3 высокоприоритетных слова. На WB заголовок индексируется с наибольшим весом.

Описание — естественное вхождение 10-15 ключевых слов. Не спам, а читаемый текст, в который органично вписаны целевые запросы.

Характеристики — заполнить ВСЕ доступные поля. Каждое заполненное поле = дополнительный шанс на ранжирование.

Порядок приоритетов:

  1. Заголовок: 3-5 главных ключей (высокий приоритет из gap-анализа)
  2. Описание: 10-15 ключей (высокий + средний приоритет)
  3. Характеристики: все релевантные ключи
  4. Инфографика: дополнительные ключи как текст на изображениях

Пример переписанного заголовка:

Было:  "Ароматизатор в машину подвесной"
Стало: "Ароматизатор автомобильный подвесной | Автопарфюм для авто |
Освежитель воздуха в машину натуральный"

2. Инфографика с SEO-текстом

WB индексирует текст на изображениях!

Многие селлеры не знают, но алгоритм Wildberries распознаёт и индексирует текст, размещённый на инфографике (OCR). Это означает, что инфографика = дополнительный канал SEO-оптимизации.

Правила:

  • Текст на инфографике должен быть читаемым (не мелкий шрифт)
  • Используйте ключевые слова естественно — как УТП и буллиты
  • Не спамьте — 3-5 ключевых фраз на слайд, вписанных в дизайн
  • Каждый слайд инфографики — возможность добавить новое ключевое слово

Fotofactor встраивает пропущенные ключевые слова в инфографику как текстовые оверлеи:

СлайдВизуалSEO-текст на слайде
1 (главный)Продукт крупным планом«Автопарфюм премиум-класса»
2Продукт в интерьере авто«Ароматизатор для авто — стойкий запах 45 дней»
3Размеры и комплектация«Освежитель воздуха в машину — компактный размер»
4Преимущества (буллиты)«Натуральный ароматизатор автомобильный подвесной»

3. Rich-контент: буллиты и характеристики

Все пропущенные ключевые слова интегрируются в:

  • Буллит-поинты карточки — каждый буллит = одно ключевое слово в естественном контексте
  • Характеристики товара — заполнение всех доступных полей с релевантными ключами
  • Описание — связный текст с органичным вхождением 10-15 ключей

4. A/B тестирование

Fotofactor предлагает клиенту сравнительный тест:

ПараметрВариант A (текущий)Вариант B (SEO-оптимизированный)
ЗаголовокСтарыйС gap-ключевыми словами
ИнфографикаБез SEO-текстаС ключевыми словами
ОписаниеИнтуитивноеData-driven
Период теста14 дней
МетрикиПоказы, клики, конверсияПоказы, клики, конверсия

5. Ежемесячный мониторинг позиций

После оптимизации — повторный запрос by_keywords через 2-4 недели для замера результата. Это переходит в Кейс «Позиционный радар» — регулярный трекинг позиций по ключевым словам.

Результат для клиента

Что получает селлер

  • Конкретный список пропущенных ключевых слов с приоритизацией (не абстрактные советы)
  • Новый заголовок и описание с SEO-оптимизацией на основе данных
  • Инфографику с интегрированными ключевыми словами
  • Матрицу сравнения с ТОП-3 конкурентами
  • Прогноз — ожидаемый рост показов на 20-30% в течение 2 недель

Типичные результаты

МетрикаДо оптимизацииПосле (2 недели)Изменение
Ключевых слов в ТОП-5015-2035-50+100-150%
Ежедневные показы2 000-5 0005 000-12 000+150-200%
CTR (клики / показы)3-5%4-7%+30-40%
SEO-gap vs конкуренты40-60 слов10-15 слов-75%
Почему результат виден через 2 недели?

Wildberries переиндексирует карточки не мгновенно. После изменения заголовка, описания и инфографики проходит 3-7 дней до полной переиндексации. Ещё 7 дней нужно для стабилизации позиций. Поэтому первый замер — через 14 дней, итоговый — через 30 дней.

Экономика для Fotofactor

УслугаСтоимостьЧто входит
SEO-аудит карточки (gap-анализ)15 000-25 000 ₽Матрица ключевых слов, сравнение с 3 конкурентами
SEO-оптимизация текстов30 000-50 000 ₽Новый заголовок, описание, характеристики, буллиты
Редизайн инфографики с SEO40 000-60 000 ₽5-8 слайдов с ключевыми словами
Комплекс «Ключ к поиску»70 000-100 000 ₽Аудит + тексты + инфографика
Ежемесячный мониторинг15 000-20 000 ₽/месПовторный gap-анализ, корректировка ключей

Средний чек: 70 000-100 000 ₽ за комплексную SEO-оптимизацию карточки.

Рекурентная выручка: ежемесячный мониторинг позиций — 15 000-20 000 ₽/мес на клиента. SEO на маркетплейсах требует постоянной корректировки, поэтому клиенты остаются на подписке.

Себестоимость пайплайна

КомпонентСтоимость
MPStats API (подписка)5 990 ₽/мес
4 запроса by_keywords на клиента~0.5 ₽ (входит в подписку)
Время аналитика на отчёт~1 час
Время копирайтера на тексты~2 часа
Время дизайнера на инфографику~4 часа
Итого на клиента~7 часов работы

Воронка продажи услуги

graph TD
A["Клиент заказывает<br/>бесплатный аудит категории<br/>(Кейс 1)"] --> B["В PDF-отчёте раздел<br/>'SEO-gap: вы теряете<br/>трафик по 40+ запросам'"]
B --> C{"Клиент видит<br/>пропущенные ключевые<br/>слова?"}
C -->|"Да, хочу исправить"| D["Комплекс 'Ключ к поиску'<br/>70 000-100 000 ₽"]
C -->|"Пока подумаю"| E["Получает бесплатный<br/>мини-список из 5 gap-слов"]
D --> F["Оптимизация карточки<br/>2-3 недели"]
E --> G["Через 2 недели: письмо<br/>'Конкуренты добавили<br/>новые ключевые слова'"]
F --> H["Ежемесячный мониторинг<br/>15 000-20 000 ₽/мес"]
G --> D