Содержание
Продавцы на маркетплейсах тратят огромное количество времени на рутину: обновление остатков, изменение цен, ответы на отзывы, выгрузку заказов. При работе с несколькими площадками это превращается в кошмар — данные расходятся, менеджеры не успевают, штрафы за стокаут растут.
Python + официальные API решают всё это автоматически.
1. Типичные проблемы при ручной работе
- Расхождение остатков — продали на WB, забыли обновить на Ozon — штраф за отмену
- Устаревшие цены — конкурент снизил цену, вы узнали через день — потеряли продажи
- Задержка обработки заказов — менеджер не проверил кабинет вовремя — просрочка сборки
- Непроработанные отзывы — негативные отзывы без ответа снижают рейтинг
- Нет сводной аналитики — данные по площадкам в разных кабинетах, сводить вручную
2. API Wildberries и Ozon
Wildberries API
- Документация:
openapi.wildberries.ru - Авторизация: API-ключ из личного кабинета (Профиль → Настройки → Доступ к API)
- Базовый URL:
https://suppliers-api.wildberries.ru - Лимиты: 5–60 запросов/мин в зависимости от метода
Ozon API
- Документация:
docs.ozon.ru/api/seller - Авторизация: Client-Id + Api-Key из личного кабинета
- Базовый URL:
https://api-seller.ozon.ru - Лимиты: 1000–10000 запросов/мин в зависимости от метода
# pip install requests import requests from typing import Optional class WildberriesAPI: BASE_URL = 'https://suppliers-api.wildberries.ru' def __init__(self, api_key: str): self.headers = { 'Authorization': api_key, 'Content-Type': 'application/json' } def _get(self, endpoint: str, params: dict = None): resp = requests.get( f'{self.BASE_URL}{endpoint}', headers=self.headers, params=params ) resp.raise_for_status() return resp.json() def _post(self, endpoint: str, data: dict): resp = requests.post( f'{self.BASE_URL}{endpoint}', headers=self.headers, json=data ) resp.raise_for_status() return resp.json() class OzonAPI: BASE_URL = 'https://api-seller.ozon.ru' def __init__(self, client_id: str, api_key: str): self.headers = { 'Client-Id': client_id, 'Api-Key': api_key, 'Content-Type': 'application/json' } def _post(self, endpoint: str, data: dict): resp = requests.post( f'{self.BASE_URL}{endpoint}', headers=self.headers, json=data ) resp.raise_for_status() return resp.json()
3. Синхронизация остатков
Самая критичная задача — синхронизация остатков между вашей системой учёта (1С, база данных) и маркетплейсами. Запускается каждые 15–30 минут.
def sync_stocks_to_wb(wb: WildberriesAPI, stocks: list[dict]): """ stocks = [{'sku': '123456', 'amount': 50}, ...] sku — баркод товара на WB """ payload = {'stocks': [ {'sku': s['sku'], 'amount': s['amount']} for s in stocks ]} result = wb._post('/api/v3/stocks/{warehouseId}', payload) return result def sync_stocks_to_ozon(ozon: OzonAPI, stocks: list[dict]): """ stocks = [{'offer_id': 'ART-001', 'stock': 50, 'warehouse_id': 123}] offer_id — артикул товара в вашей системе """ payload = {'stocks': [ { 'offer_id': s['offer_id'], 'stock': s['stock'], 'warehouse_id': s['warehouse_id'] } for s in stocks ]} result = ozon._post('/v2/products/stocks', payload) return result # Основная функция синхронизации def sync_all_stocks(): # Получаем актуальные остатки из 1С или БД stocks = get_stocks_from_db() # Синхронизируем на обе площадки параллельно import concurrent.futures with concurrent.futures.ThreadPoolExecutor() as ex: wb_future = ex.submit(sync_stocks_to_wb, wb, prepare_wb_stocks(stocks)) oz_future = ex.submit(sync_stocks_to_ozon, ozon, prepare_ozon_stocks(stocks)) print(f'Синхронизировано {len(stocks)} позиций на WB и Ozon')
4. Автоматическое обновление цен
Репрайсер — инструмент который следит за ценами конкурентов и автоматически корректирует ваши цены по заданным правилам.
def update_prices_ozon(ozon: OzonAPI, prices: list[dict]): """Обновление цен на Ozon""" payload = {'prices': [ { 'offer_id': p['offer_id'], 'price': str(p['price']), 'old_price': str(p.get('old_price', '')), 'min_price': str(p.get('min_price', '')), } for p in prices ]} return ozon._post('/v1/product/import/prices', payload) def repricer(my_price: float, competitor_price: float, min_price: float, max_price: float) -> float: """Простой репрайсер: держимся на 1% ниже конкурента""" target = competitor_price * 0.99 # Не опускаемся ниже минимума и не поднимаемся выше максимума return max(min_price, min(max_price, target))
5. Получение и обработка заказов
def get_new_orders_wb(wb: WildberriesAPI) -> list: """Получить новые заказы с WB за последние 24 часа""" from datetime import datetime, timedelta date_from = (datetime.now() - timedelta(hours=24)).strftime('%Y-%m-%dT%H:%M:%SZ') result = wb._get('/api/v3/orders', {'dateFrom': date_from, 'limit': 1000}) return result.get('orders', []) def process_new_orders(): """Основной цикл обработки новых заказов""" wb_orders = get_new_orders_wb(wb) ozon_orders = get_new_orders_ozon(ozon) all_orders = wb_orders + ozon_orders new_count = 0 for order in all_orders: order_id = order.get('id') or order.get('order_id') # Проверяем не обработан ли уже if order_exists_in_db(order_id): continue # Сохраняем в БД save_order_to_db(order) # Создаём задачу на сборку create_assembly_task(order) # Уведомляем склад в Telegram send_telegram( f'📦 Новый заказ #{order_id}\n' f'Площадка: {order.get("marketplace", "WB")}\n' f'Товар: {order.get("article", "")}' ) new_count += 1 print(f'Обработано новых заказов: {new_count}')
6. Авто-ответы на отзывы
Отвечать на каждый отзыв вручную — часы работы. Система авто-ответов обрабатывает типовые отзывы автоматически, сложные передаёт менеджеру:
import openai def generate_review_reply(review_text: str, rating: int) -> str: """Генерация ответа на отзыв с помощью GPT-4""" tone = 'сочувствующий и решающий проблему' if rating <= 3 else 'благодарный' response = openai.chat.completions.create( model='gpt-4o', messages=[{ 'role': 'system', 'content': f"""Ты менеджер интернет-магазина. Пиши короткие (2-3 предложения), искренние ответы на отзывы. Тон: {tone}. Не используй шаблонные фразы.""" }, { 'role': 'user', 'content': f'Отзыв (оценка {rating}/5): {review_text}' }] ) return response.choices[0].message.content def process_reviews_ozon(ozon: OzonAPI): """Обработать неотвеченные отзывы на Ozon""" reviews = ozon._post('/v1/review/list', { 'status': 'ALL', 'limit': 100 }).get('reviews', []) for review in reviews: if review.get('comment_for_review'): continue # уже отвечено rating = review['rating'] text = review.get('text', '') # Низкие оценки — передаём менеджеру if rating <= 2: send_telegram(f'⚠️ Низкий отзыв {rating}⭐:\n{text[:200]}') continue # Генерируем и публикуем ответ reply = generate_review_reply(text, rating) ozon._post('/v1/review/comment/create', { 'review_id': review['id'], 'text': reply })
7. Аналитика продаж
Сводная аналитика по всем площадкам в одном месте — ежедневный отчёт в Telegram или Google Sheets:
def daily_analytics_report(): """Ежедневный отчёт в Telegram""" from datetime import date, timedelta yesterday = date.today() - timedelta(days=1) # Получаем данные с обеих площадок wb_sales = get_wb_sales(yesterday) ozon_sales = get_ozon_sales(yesterday) total_revenue = wb_sales['revenue'] + ozon_sales['revenue'] total_orders = wb_sales['orders'] + ozon_sales['orders'] report = f""" 📊 *Отчёт за {yesterday.strftime('%d.%m.%Y')}* 💰 Выручка: {total_revenue:,.0f} ₽ 📦 Заказов: {total_orders} 🛍 Wildberries: • Выручка: {wb_sales['revenue']:,.0f} ₽ • Заказов: {wb_sales['orders']} • Возвраты: {wb_sales['returns']} 🔵 Ozon: • Выручка: {ozon_sales['revenue']:,.0f} ₽ • Заказов: {ozon_sales['orders']} • Отмены: {ozon_sales['cancels']} """ send_telegram(report)
8. Архитектура системы
Рекомендуемая архитектура для автоматизации маркетплейсов:
- VPS-сервер — Ubuntu, 2 CPU, 4 GB RAM (~1 000 ₽/мес)
- PostgreSQL — хранение заказов, остатков, истории цен
- Cron-задачи — синхронизация остатков каждые 15 мин, заказы каждые 5 мин
- Telegram-бот — уведомления и управление
- Grafana — дашборд с аналитикой продаж
Нужна автоматизация маркетплейсов под ключ?
Настраиваем интеграцию с WB, Ozon и Яндекс Маркет: остатки, цены, заказы, отзывы. От 40 000 ₽, срок 2–3 недели.
Получить оценку