110 lines
4.1 KiB
Python
110 lines
4.1 KiB
Python
import requests
|
||
import time
|
||
import os
|
||
import pandas as pd
|
||
from datetime import datetime, timedelta
|
||
|
||
# Импортируем заголовки (Client-Id и Api-Key), должны быть в файле ozon_data.py
|
||
from ozon_data import headers
|
||
|
||
# URL эндпоинтов
|
||
url_analytics = "https://api-seller.ozon.ru/v1/analytics/data"
|
||
url_product_list = "https://api-seller.ozon.ru/v3/product/info/list"
|
||
|
||
# Автоматически определяем даты: за последние 7 дней
|
||
date_to = datetime.today().date()
|
||
date_from = date_to - timedelta(days=7)
|
||
|
||
# Преобразуем даты в строку для запроса
|
||
date_from_str = str(date_from)
|
||
date_to_str = str(date_to)
|
||
|
||
# Тело запроса
|
||
payload = {
|
||
"date_from": date_from_str,
|
||
"date_to": date_to_str,
|
||
"dimension": ["sku"],
|
||
"metrics": ["ordered_units", "hits_view_pdp"],
|
||
"limit": 1000
|
||
}
|
||
|
||
try:
|
||
response = requests.post(url_analytics, headers=headers, json=payload)
|
||
response.raise_for_status()
|
||
data = response.json()
|
||
|
||
# Парсим результат
|
||
result_data = []
|
||
for item in data.get("result", {}).get("data", []):
|
||
dimensions = item.get("dimensions", [])
|
||
metrics = item.get("metrics", [])
|
||
|
||
row = {
|
||
"sku": dimensions[0].get("id") if len(dimensions) > 0 else None,
|
||
"ordered_units": metrics[0] if len(metrics) > 0 else 0,
|
||
"hits_view_pdp": metrics[1] if len(metrics) > 1 else 0,
|
||
}
|
||
result_data.append(row)
|
||
|
||
df = pd.DataFrame(result_data)
|
||
|
||
# --- Шаг 2: Запрашиваем названия товаров через /v3/product/info/list ---
|
||
skus = df["sku"].dropna().astype(int).unique().tolist()
|
||
|
||
# Разбиваем на чанки по 1000 штук (если больше 1000)
|
||
def chunked(lst, n):
|
||
"""Разбивает список на части по n элементов"""
|
||
return [lst[i:i + n] for i in range(0, len(lst), n)]
|
||
|
||
for chunk in chunked(skus, 1000): # Ozon позволяет до 1000 SKU за раз
|
||
payload_products = {
|
||
"sku": chunk
|
||
}
|
||
|
||
try:
|
||
response_products = requests.post(url_product_list, headers=headers, json=payload_products)
|
||
response_products.raise_for_status()
|
||
data_products = response_products.json()
|
||
|
||
if "items" not in data_products:
|
||
print("Ошибка: В ответе нет ключа 'items'")
|
||
continue
|
||
|
||
for item in data_products.get("items", []):
|
||
el_sku = item["sources"][0]["sku"]
|
||
if el_sku and "name" in item:
|
||
df.loc[df['sku'] == str(el_sku), 'name'] = item['name']
|
||
else:
|
||
print("Ошибка в элементе товара — нет 'sku' или 'name':")
|
||
|
||
except requests.exceptions.RequestException as e:
|
||
print(f"Ошибка запроса к /v3/product/info/list: {e}")
|
||
if e.response:
|
||
print("Текст ответа:", e.response.text)
|
||
|
||
# Добавляем колонку: конверсия заказов к показам * 100
|
||
df["conversion_ordered_to_views (%)"] = (
|
||
df["ordered_units"] / df["hits_view_pdp"] * 100
|
||
).round(2)
|
||
|
||
# Создаем папку для вывода
|
||
output_dir = "result"
|
||
if not os.path.exists(output_dir):
|
||
os.makedirs(output_dir)
|
||
|
||
# Имя файла на основе скрипта
|
||
script_name = os.path.splitext(os.path.basename(__file__))[0]
|
||
filename = f"{script_name}_analytics_conversion_{date_from_str}_{date_to_str}"
|
||
csv_filename = os.path.join(output_dir, f"{filename}.csv")
|
||
xls_filename = os.path.join(output_dir, f"{filename}.xlsx")
|
||
|
||
# Сохраняем
|
||
df.to_csv(csv_filename, index=False, encoding="utf-8-sig")
|
||
df.to_excel(xls_filename, index=False)
|
||
|
||
print(f"Данные успешно сохранены в {csv_filename}")
|
||
|
||
except requests.exceptions.RequestException as e:
|
||
print(f"Ошибка при выполнении запроса: {e}")
|
||
except Exception as e:
|
||
print(f"Ошибка обработки данных: {e}") |