AI Парсинг цен и данных о товарах конкурентов на Wildberries

Регистрация
23 Август 2023
Сообщения
2 819
Лучшие ответы
0
Реакции
0
Баллы
51
Offline
#1
Всем привет!

Ранее я уже писал про парсинг Wildberries, но та статья была довольно узконаправленной и не затрагивала более широкие возможности анализа. Да и с тех пор многое изменилось — тема стала ещё актуальнее, а у читателей накопилось больше вопросов.

Поэтому в этой статье мы разберём тему заново, но уже с акцентом на практическую пользу. Мы разберём:


  • как достать данные о товарах и ценах из WB,


  • как превратить их в удобные таблицы или графики,


  • и как использовать их для анализа конкурентов и рынка в целом.

Всё это будет реализовано на Python.


Все примеры приведены исключительно в образовательных целях. Для коммерческой работы у Wildberries есть официальный Public API.
Где искать данные для парсинга?


Первый вопрос, который возникает у любого, кто хочет парсить Wildberries: а где вообще лежат данные?

Ответ прост: прямо в браузере. Когда мы открываем карточку товара или каталог, сайт делает фоновые запросы к API и принимает информацию в формате JSON.

Посмотреть их можно в DevTools (панель разработчика в браузере):


  1. Откройте любую страницу на Wildberries.


  2. Нажмите F12 - вкладка Network - фильтр Fetch/XHR.


  3. Обновите страницу (CTRL+F5).


  4. В списке запросов вы увидите адреса вида:

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

Пример ответа для одного товара:

"products":[
{
"__msort":113473,
"mrel":9862,
"mksort":65,
"id":124063338,
"time1":3,
"time2":60,
"wh":117986,
"dtype":6597069766664,
"dist":991,
"root":110497359,
"kindId":0,
"brand":"НА ПРИМЕР",
"brandId":313700,
"siteBrandId":0,
"colors":[

],
"subjectId":4961,
"subjectParentId":786,
"name":"Комиксы детские для мальчиков 5-11 лет",
"entity":"книги-комиксы",
"matchId":131554853,
"supplier":"ОП!",
"supplierId":222339,
"supplierRating":4.7,
"supplierFlags":12224,
"pics":18,
"rating":5,
"reviewRating":4.7,
"nmReviewRating":4.7,
"feedbacks":45,
"nmFeedbacks":45,
"panelPromoId":1009972,
"volume":3,
"viewFlags":1581072,
"sizes":[
{
"name":"",
"origName":"0",
"rank":0,
"optionId":218050475,
"wh":117986,
"time1":3,
"time2":60,
"dtype":6597069766664,
"price":{
"basic":160000,
"product":33700,
"logistics":300,
"return":0
},
"saleConditions":146800640,
"payload":"длинная-строка"
}
],
"totalQuantity":1,
"meta":{
"tokens":[

]
}
},
...


Панель разработчика с информацией об API

Итак, перейдём к практике.

Шаг 0: Как устроен URL поиска Wildberries и что означают его параметры


Когда мы работаем с данными Wildberries через внутреннее API, мы обращаемся к URL вроде этого:

url = f"https://search.wb.ru/exactmatch/ru/common/v18/search?appType=1&curr=rub&dest=-1257786&lang=ru&page=1&query={query}&resultset=catalog&sort=popular&spp=30"

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

Основные параметры


  • appType — тип приложения: 1 = веб, 4 = мобильное. Влияет на формат данных.


  • curr — валюта: rub - рубли, usd - доллары и т.д.


  • dest — регион или склад. Определяет наличие товара и цену.


  • lang — язык интерфейса и описаний товаров.


  • page — номер страницы поиска. Позволяет листать результаты.


  • query — поисковый запрос, например "смартфон" или "наушники".


  • resultset — скорее всего тип поиска. Обычно catalog.


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


  • spp — количество товаров на одной странице.
Шаг 1. Минимальный парсер Wildberries


Для запуска нужен Python >=3.11 и библиотеки requests и pandas

import requests
import pandas as pd

# Создаем строку (пока query = захардкоженое значение)
query = "смартфон"
url = f"https://search.wb.ru/exactmatch/ru/...st=-1257786&lang=ru&page=1&query={query}&resultset=catalog&sort=popular&spp=30"

response = requests.get(url)
data = response.json()

# Получаем список продуктов
products = data.get("products", [])

# Преобразуем данные в удобный для создания DataFrame вид
items = []
for p in products:
item = {
"id": p.get("id"),
"name": p.get("name"),
"brand": p.get("brand"),
"price": p.get("sizes", [{}])[0].get("price", {}).get("product", 0) / 100, # цена в рублях
"rating": p.get("rating", 0),
"feedbacks": p.get("feedbacks", 0)
}
items.append(item)

df = pd.DataFrame(items)
print(df.head())

# Сохраняем в CSV
df.to_csv("test.csv", index=False)

Что делает этот код:


  1. Достает данные с Wildberries по запросу query.


  2. Берёт нужные поля: id,name,brand,price,rating,feedbacks.


  3. Преобразует в таблицу pandas DataFrame.


  4. Сохраняет в CSV, чтобы можно было удобно анализировать и строить графики.

После выполнения кода выше получаем test.csv с содержимым:

id,name,brand,price,rating,feedbacks
507623823,Смартфон Redmi 13C 8ГБ 256 ГБ 90гц Аndroid синий,Xiaomi,6121.0,5,4
518695516,Смартфон Y19 8 256 ГБ Черный,VIVO,4320.0,0,0
309442000,Смартфон Frbby F10 4 128GB 5000mAh черный,,5301.0,5,53
488478649,Смартфон realne 13C 6 128ГБ,,4517.0,4,15
256099131,"M-HORSE, Смартфон P70 64 ГБ 5000 мАч Светло-серый",MI,4143.0,4,84
365784152,"Смартфон Y04 4+128 Гб, малахитовый черный",vivo,8567.0,5,95
440536590,SPARK Go 1 4+128GB,TECNO,6754.0,5,107
478600034,Galaxy A16 4+128GB,Samsung,10995.0,5,23
384497995,Смартфон A55 Plus 12+512+Разблокировка по лицу и отпечатку,,5569.0,4,68
342395239,SPARK Go 1 3+64GB,TECNO,4945.0,5,150
507519429,Смартфон Y71 6 128 Gb Черный,VIVO,2760.0,5,2
480685679,Смартфон SPARK 40C 128+8GB Ink Black,TECNO,9272.0,5,39
...
Шаг 2. Визуализация данных


После того как мы собрали данные о товарах и ценах из Wildberries и сохранили их в CSV (test.csv), следующим шагом будет анализ и визуализация. Это позволит быстро понять, какие бренды популярны, как распределены цены, и где есть возможности для конкуренции.

Мы будем использовать Python, а именно библиотеки:


  • pandas — для работы с таблицами,


  • matplotlib и seaborn — для графиков.
2.1. Гистограмма цен


Сначала посмотрим, как распределены цены на смартфоны:

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

df = pd.read_csv("test.csv")

plt.figure(figsize=(10,6))
sns.histplot(df['price'], bins=20, kde=True)
plt.title("Распределение цен на смартфоны")
plt.xlabel("Цена, руб")
plt.ylabel("Количество товаров")
plt.tight_layout()
plt.savefig("price.png")
plt.close()


Вывод сохраняется в price.png:


Гистограмма распределения цен, полученных в нашем парсере Wildberries
2.2. Топ брендов по количеству товаров


Теперь посмотрим, какие бренды представлены больше всего:

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

df = pd.read_csv("test.csv")

top_brands = df['brand'].value_counts().head(10)
plt.figure(figsize=(10,6))
sns.barplot(x=top_brands.index, y=top_brands.values)
plt.title("Топ-10 брендов по количеству товаров")
plt.xlabel("Бренд")
plt.ylabel("Количество товаров")
plt.xticks(rotation=45)
plt.tight_layout()
plt.savefig("brands_count.png")
plt.close()


Вид brands_count.png:


Гистограмма распределения брендов, полученных в нашем парсере Wildberries
2.3. Топ брендов по средней цене


Интересно также посмотреть, у каких брендов самые дорогие товары:

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

df = pd.read_csv("test.csv")

brand_price = df.groupby('brand')['price'].mean().sort_values(ascending=False).head(10)
plt.figure(figsize=(10,6))
sns.barplot(x=brand_price.index, y=brand_price.values)
plt.title("Топ-10 брендов по средней цене")
plt.xlabel("Бренд")
plt.ylabel("Средняя цена, руб")
plt.xticks(rotation=45)
plt.tight_layout()
plt.savefig("brands_avg_price.png")
plt.close()


График brands_avg_price.png:


Гистограмма распределения брендов по цене
Шаг 3. Создаём Телеграм-бота для анализа Wildberries


Теперь мы можем сделать бота, которому достаточно написать команду /search <запрос>;, а бот:


  1. Получает товары с WB по вашему запросу,


  2. Строит графики и сохраняет их в PNG,


  3. Отправляет графики пользователю.
3.1. Установка зависимостей


В проекте будут использованы следующие зависимости:


  • aiogram — для бота Telegram


  • pandas — работа с таблицами


  • matplotlib и seaborn — графики


  • requests — запросы к API WB


  • python-dotenv — хранение токена бота в .env (нужно только локально, в Amvera будем использовать интерфейс)

Если будете тестировать локально — создайте .env с содержимым:

TOKEN=ВАШ_ТОКЕН_ТЕЛЕГРАМ

Напишем файл requirements.txt, содержащий список наших зависимостей. Это поможет нам в дальнейшем развертывании решения.

requirements.txt:

aiogram==3.22.0
requests==2.32.5
pandas==2.3.2
matplotlib==3.10.6
seaborn==0.13.2
python-dotenv==1.1.1
3.2. Код бота


import asyncio
import requests
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import io
import logging
import os

from dotenv import load_dotenv

from aiogram import Bot, Dispatcher, types, F
from aiogram.types import InlineKeyboardButton, CallbackQuery, InputFile
from aiogram.filters import CommandStart, Command, CommandObject
from aiogram.utils.keyboard import InlineKeyboardBuilder
from aiogram.client.default import DefaultBotProperties
from aiogram.enums.parse_mode import ParseMode

logging.basicConfig(level=logging.INFO)
load_dotenv()

bot = Bot(os.getenv("TOKEN"), default=DefaultBotProperties(parse_mode=ParseMode.HTML)) # Создайте переменную окружения TOKEN с токеном вашего бота
dp = Dispatcher()

@dp.message(Command("search"))
async def search_wb(message: types.Message):
query = message.text.split(" ", 1)[1]
if not query:
await message.answer("Пожалуйста, укажи, что искать: /search &lt;запрос&gt;")
return

await message.answer(f"Ищу товары по запросу: {query}...")

# Получаем и парсим данные
url = f"https://search.wb.ru/exactmatch/ru/...st=-1257786&amp;lang=ru&amp;page=1&amp;query={query}&amp;resultset=catalog&amp;sort=popular&amp;spp=30"
response = requests.get(url)
data = response.json()
products = data.get("products", [])

items = []
for p in products:
item = {
"id": p.get("id"),
"name": p.get("name"),
"brand": p.get("brand"),
"price": p.get("sizes", [{}])[0].get("price", {}).get("product", 0) / 100,
"rating": p.get("rating", 0),
"feedbacks": p.get("feedbacks", 0)
}
items.append(item)

df = pd.DataFrame(items)

if df.empty:
await message.answer("По вашему запросу товаров не найдено.")
return

# 1. Гистограмма цен
plt.figure(figsize=(8,5))
sns.histplot(df['price'], bins=20, kde=True)
plt.title("Распределение цен")
plt.xlabel("Цена, руб")
plt.ylabel("Количество товаров")
price_buf = io.BytesIO()
plt.savefig(price_buf, format='png')
price_buf.seek(0)
plt.close()

# 2. Топ-10 брендов по количеству
top_brands = df['brand'].value_counts().head(10)
plt.figure(figsize=(8,5))
sns.barplot(x=top_brands.index, y=top_brands.values)
plt.title("Топ-10 брендов по количеству товаров")
plt.xlabel("Бренд")
plt.ylabel("Количество")
plt.xticks(rotation=45)
brands_count_buf = io.BytesIO()
plt.savefig(brands_count_buf, format='png')
brands_count_buf.seek(0)
plt.close()

# 3. Топ-10 брендов по средней цене
brand_price = df.groupby('brand')['price'].mean().sort_values(ascending=False).head(10)
plt.figure(figsize=(8,5))
sns.barplot(x=brand_price.index, y=brand_price.values)
plt.title("Топ-10 брендов по средней цене")
plt.xlabel("Бренд")
plt.ylabel("Средняя цена, руб")
plt.xticks(rotation=45)
brands_avg_price_buf = io.BytesIO()
plt.savefig(brands_avg_price_buf, format='png')
brands_avg_price_buf.seek(0)
plt.close()

# Отправляем все 3 графика
await message.answer_photo(types.BufferedInputFile(price_buf.getvalue(), filename='price.png'))
await message.answer_photo(types.BufferedInputFile(brands_count_buf.getvalue(), filename='brands_count.png'))
await message.answer_photo(types.BufferedInputFile(brands_avg_price_buf.getvalue(), filename='brands_avg_price.png'))

async def on_start():
await bot.delete_webhook(drop_pending_updates=True)
await dp.start_polling(bot)

if __name__ == "__main__":
asyncio.run(on_start())

3.3. Что умеет бот


  1. По команде /search <запрос>; собирает товары Wildberries.


  2. Формирует три графика:

    • распределение цен,


    • топ-10 брендов по количеству товаров,


    • топ-10 брендов по средней цене.

  3. Отправляет графики в PNG, готовые для анализа

Получаем данные парсинга в боте

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

Итог


В этой статье мы разобрали, как собрать и проанализировать данные о товарах и ценах с Wildberries и реализовали:


  1. Парсинг данных — через внутренние API Wildberries, получая JSON с товарами, брендами, ценами, рейтингами и отзывами.


  2. Обработку и визуализацию — с помощью pandas, matplotlib и seaborn можно строить таблицы и графики для анализа конкурентов.


  3. Автоматизацию через Telegram-бота — бот позволяет быстро получать аналитику по любому запросу прямо в чат, с готовыми графиками.

Релевантная статья:

 
Сверху Снизу