3. Код для работы с Ozon API
Создайте файл ozon_rich_content.py:
python
import os
import requests
import time
from dotenv import load_dotenv
from PIL import Image
from io import BytesIO
# Загрузка ключей из .env
load_dotenv()
API_KEY = os.getenv("OZON_API_KEY")
CLIENT_ID = os.getenv("OZON_CLIENT_ID")
API_URL = "https://api-seller.ozon.ru"
# Заголовки для запросов
headers = {
"Client-Id": CLIENT_ID,
"Api-Key": API_KEY,
"Content-Type": "application/json"
}
def get_product_list():
"""Получить список всех товаров"""
url = f"{API_URL}/v2/product/list"
payload = {
"filter": {},
"limit": 1000 # Максимальное количество товаров
}
response = requests.post(url, json=payload, headers=headers)
return response.json()["result"]["items"]
def get_product_info(product_id):
"""Получить описание и фото товара"""
url = f"{API_URL}/v1/product/info"
payload = {
"product_id": product_id,
"offer_id": "" # Замените на offer_id, если используете
}
response = requests.post(url, json=payload, headers=headers)
data = response.json()
return {
"description": data.get("description", ""),
"images": [img["file_name"] for img in data.get("images", [])]
}
def upload_rich_content(product_id, content_json):
"""Обновить rich-контент"""
url = f"{API_URL}/v1/product/import/info/update"
payload = {
"items": [{
"product_id": product_id,
"description_details": content_json
}]
}
response = requests.post(url, json=payload, headers=headers)
return response.json()
def process_images(image_urls):
"""Обработка изображений (пример)"""
processed = []
for url in image_urls:
response = requests.get(url)
img = Image.open(BytesIO(response.content))
img = img.resize((1200, 1600)) # Подгон под требования Ozon
# Сохранение в временный файл (или загрузка на сервер)
img.save(f"temp_{url.split('/')[-1]}")
processed.append(f"temp_{url.split('/')[-1]}")
return processed
# Основной скрипт
if __name__ == "__main__":
products = get_product_list()
for product in products:
product_id = product["product_id"]
print(f"Обрабатываю товар ID: {product_id}")
# Получить данные
product_info = get_product_info(product_id)
description = product_info["description"]
images = product_info["images"]
# Обработать изображения (если требуется)
processed_images = process_images(images) # Раскомментируйте, если нужно
# Сформировать rich-контент
rich_content = {
"components": [
{"type": "text", "content": description},
{"type": "images", "urls": images} # Используйте processed_images, если обработали
]
}
# Отправить на Ozon
result = upload_rich_content(product_id, rich_content)
print(f"Результат: {result}")
time.sleep(1) # Чтобы не превысить лимиты API
4. Пояснения к коду
a. Получение списка товаров
Метод /v2/product/list возвращает все товары магазина.
Лимит 1000 можно изменить, если товаров больше.
b. Извлечение данных
get_product_info получает описание и список URL изображений.
Ozon требует file_name вместо URL для изображений — убедитесь, что они уже загружены в карточку.
c. Обработка изображений
Функция process_images скачивает изображения, меняет размер и сохраняет локально.
Если Ozon требует загружать изображения через API, используйте метод /v1/product/import/images.
d. Структура rich-контента
Формат description_details должен соответствовать требованиям Ozon. Пример:
json
{
"components": [
{
"type": "text",
"content": "Электрический чайник с защитой от перегрева..."
},
{
"type": "images",
"urls": ["image1.jpg", "image2.jpg"]
}
]
}
5. Запуск скрипта
bash
python ozon_rich_content.py
6. Ошибки и проверка
Возможные ошибки:
403 Forbidden: Неверные API-ключи или права доступа.
429 Too Many Requests: Превышен лимит запросов. Увеличьте задержку time.sleep().
400 Bad Request: Неверный формат JSON. Проверьте структуру description_details.
Тестирование:
Запустите скрипт для 1 товара, закомментировав цикл for.
Проверьте карточку товара в личном кабинете Ozon.
7. Дополнительные настройки
Оптимизация изображений: Используйте Pillow для сжатия:
python
img.save("image.jpg", optimize=True, quality=85)
Логирование: Добавьте запись ошибок в файл:
python
import logging
logging.basicConfig(filename='errors.log', level=logging.ERROR)