Разработка · 6 мин чтения

Парсер Wildberries по артикулу на Python: пошаговая инструкция

Артикул Wildberries (в адресной строке и в API он называется nmId) - единственный параметр, который нужен, чтобы вытащить из маркетплейса полную карточку товара: цену, скидку, остатки по складам, рейтинг и количество отзывов. Парсер wildberries по артикулу я обычно собираю за час-полтора на чистом Python без Selenium и headless-браузера - Wildberries отдаёт данные через открытый JSON-API, и вся задача сводится к правильному GET-запросу и разбору ответа. Ниже - рабочая схема, которую использую в реальных проектах: от разовой выгрузки цен конкурентов до автоматического мониторинга остатков для интернет-магазина на WooCommerce.

Как Wildberries отдаёт данные по товару

Когда открываешь карточку товара в браузере, фронтенд WB делает запрос к card.wb.ru (или к basket-*.wbbasket.ru - конкретный поддомен зависит от диапазона артикула) и получает JSON с полным описанием позиции. Авторизация не нужна - эндпоинт публичный, им же пользуется сам сайт. Из ответа обычно достаю:

  • id - тот самый артикул (nmId)
  • name, brand - название и бренд
  • salePriceU - цена со скидкой в копейках
  • totalQuantity - остаток по всем складам
  • reviewRating, feedbacks - рейтинг и число отзывов
  • sizes - размерная сетка с ценами по каждому размеру, если товар не универсальный

Важный нюанс: параметр dest в запросе задаёт регион, от него зависят цена и остатки - Wildberries показывает разным городам разные значения из-за логистики складов. Для Москвы обычно ставлю -1257786, но если нужна точность по конкретному региону, значение стоит подсмотреть в cookies реального запроса из браузера через вкладку Network.

Что понадобится для сбора данных с WB на Python

Из библиотек хватает трёх:

  • requests - для HTTP-запросов к API
  • pandas - для сборки таблицы и экспорта в Excel или CSV
  • time - для пауз между запросами, без них WB банит IP уже после 15-20 запросов подряд

Ставим одной командой:

pip install requests pandas openpyxl

Selenium, Playwright и прочие браузерные движки для этой задачи не нужны - они на порядок медленнее и тяжелее. Подключаю их только когда WB меняет защиту и требует JS-рендер, но за последний год для карточек товаров такого не случалось ни разу.

Пишем парсер: получаем карточку по одному артикулу

Вот рабочая функция, которую использую как основу почти в каждом проекте с WB:

import requests

def get_product_by_article(article: int) -> dict:
    url = "https://card.wb.ru/cards/v2/detail"
    params = {
        "appType": 1,
        "curr": "rub",
        "dest": -1257786,
        "spp": 30,
        "nm": article,
    }
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
        "Accept": "application/json",
    }
    response = requests.get(url, params=params, headers=headers, timeout=10)
    response.raise_for_status()
    data = response.json()
    product = data["products"][0]
    return {
        "id": product["id"],
        "name": product["name"],
        "brand": product["brand"],
        "price": product["salePriceU"] / 100,
        "rating": product.get("reviewRating"),
        "feedbacks": product.get("feedbacks"),
    }

if __name__ == "__main__":
    print(get_product_by_article(12345678))

Функция возвращает готовый словарь с ключевыми полями. На практике я ещё разбираю sizes, если нужна цена по каждому размеру отдельно, и product.get("subjectName") - категорию товара, она пригождается при сортировке большой выгрузки.

Бесплатный материал

🎁 Полезный скрипт в подарок

Подпишитесь на Telegram - пришлю готовый скрипт по этой теме.

Без спама. Отписка в 1 клик.

Собираю несколько артикулов и сохраняю в таблицу

Если нужно проверить не один товар, а весь ассортимент конкурента или собственный каталог из пары сотен позиций, оборачиваю функцию в цикл с паузой и складываю результат в DataFrame:

import time
import pandas as pd

articles = [12345678, 23456789, 34567890]
rows = []

for art in articles:
    try:
        rows.append(get_product_by_article(art))
    except Exception as e:
        print(f"Артикул {art}: ошибка — {e}")
    time.sleep(1.5)

df = pd.DataFrame(rows)
df.to_excel("wb_products.xlsx", index=False)

На 300 артикулах с паузой 1.5 секунды скрипт отрабатывает за 7-8 минут - для разового мониторинга нормально. Для ежедневного запуска на большом каталоге лучше распараллелить через ThreadPoolExecutor на 3-5 потоков и увеличить паузы на каждый поток отдельно, иначе быстро словишь бан по IP.

Формат экспорта выбираю по задаче:

Формат Когда использую Ограничение
CSV Разовая выгрузка, дальше данные идут в другой скрипт или БД Неудобно смотреть глазами, слетает кодировка при открытии в Excel напрямую
Excel (xlsx) Отчёт для заказчика или менеджера, нужны формулы и сортировка Медленнее пишется на больших объёмах, от 5000+ строк
Google Таблицы Данные должны обновляться автоматически и быть доступны команде Нужна авторизация через service account и лимиты API на запись

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

Обхожу блокировки: прокси, заголовки, паузы

Wildberries банит по IP при частых запросах без ротации - на практике порог примерно 15-20 запросов в минуту с одного адреса, дальше приходят пустые products или код 429. Что реально помогает:

  • Ротация User-Agent - держу список из 5-10 актуальных строк браузеров и меняю на каждый запрос
  • Паузы минимум 1-2 секунды между запросами, для выгрузки от 1000 артикулов прокси уже обязательны
  • Повторные попытки с задержкой при коде 429 вместо мгновенного падения скрипта
Тип прокси Когда достаточно Риск бана
Датацентровые Разовая выгрузка 50-200 товаров Средний, WB иногда банит целые подсети
Резидентные Регулярный мониторинг большого каталога Низкий, но стоят заметно дороже датацентровых
Мобильные Парсинг через фронтенд-эндпоинты, не только карточки товара Минимальный, оправдан только при высокой частоте запросов

Капчу на API карточек товара WB пока не ставит - она чаще всплывает при парсинге поисковой выдачи или отзывов через фронтенд-эндпоинты. Если добрался до неё, разумнее снизить частоту запросов, чем подключать сервисы разгадывания - это удорожает и усложняет скрипт без явной необходимости для задачи «получить карточку по артикулу».

Автоматизирую сбор: расписание, уведомления и n8n

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

  • cron на сервере - простой вариант, если скрипт запускается раз в час-два и результат нужен только в файле или базе
  • n8n - когда результат должен попадать в Google Таблицу, CRM или триггерить рассылку, оборачиваю Python-скрипт в HTTP-запрос или Execute Command ноду и строю цепочку без лишнего кода
  • Telegram-бот на aiogram - для точечных уведомлений: цена упала ниже порога или остаток на складе меньше заданного числа - бот присылает сообщение сразу, без захода в таблицу

Для интернет-магазинов на WooCommerce такую связку обычно ставлю поверх существующего каталога: парсер раз в сутки сверяет цены конкурентов по артикулам WB и подсказывает, где отстройка по цене критична. Разработка такого пайплайна под ключ - от 20 000 ₽, конкретная сумма зависит от числа источников и глубины автоматизации.

Данные и процессы на автопилоте

Парсинг / Автоматизация

от 20 000 ₽

Подробнее →

Частые вопросы

Где посмотреть артикул товара на Wildberries?

Артикул (nmId) - это число в адресной строке карточки товара, между /catalog/ и /detail.aspx, например wildberries.ru/catalog/12345678/detail.aspx означает артикул 12345678. Он же отображается на странице товара под названием с подписью «Артикул: …».

Законно ли парсить данные Wildberries по артикулу?

Данные в карточке товара публичные и доступны без авторизации - сам сайт запрашивает их у того же API. Для личного анализа цен и остатков ограничений нет, но массовый парсинг с высокой нагрузкой на серверы WB или коммерческая перепродажа собранных данных - уже вопрос пользовательского соглашения площадки. В таких случаях советую держать частоту запросов умеренной и не использовать результат для прямого копирования чужого каталога.

Почему скрипт вдруг перестаёт получать данные?

Чаще всего причина - бан IP из-за частых запросов без пауз, реже - Wildberries обновил структуру ответа API, такое случается пару раз в год, и нужно поправить пути в JSON. Проверяю оба варианта по очереди: сначала смотрю статус-код ответа (429 или пустой products - это бан), потом сверяю структуру JSON вручную через вкладку Network в браузере.

Сколько стоит заказать парсер Wildberries под ключ?

Если не хочется разбираться самостоятельно или нужна регулярная автоматизация с выгрузкой в таблицу и уведомлениями, разработка парсинга и автоматизации на Python у меня стоит от 20 000 ₽ - итоговая цена зависит от числа источников, объёма артикулов и того, нужна ли интеграция с CRM или Telegram-ботом.

Есть задача?

Обсудим в мессенджере

Расскажите, что нужно сделать — отвечу в течение 4 часов в рабочее время. Первая консультация бесплатно.

Самозанятый Калинкин Н. А. · работаю с физлицами и юрлицами

Продолжая пользование настоящим сайтом Вы выражаете своё согласие на обработку Ваших персональных данных (файлов куки) с использованием Yandex.Metrika.
Понятно