В этой статье поделимся экспериментом (опытом) написания скрипта в ИИ на языке программирования python (питон) для выгрузки данных из api поставщика svarog-rf.ru в файл.
Попалось на глаза простенькое api поставщика, где нет авторизации, множества функций и все работает просто. Один запрос дает список товаров с артикулами и ценами, остатками, второй запрос - по артикулу (ид) можно получить подробную информацию про конкретный товар. Мечта, а не api, поставщику респект за такое.
В качестве эксперимента в ИИ был отправлен запрос, состоящий из файла html страницы с документацией на api и просьбы сделать скрипт на питоне, который выгрузит информацию про товары с этого апи в csv файл.
Писать простенькие скрипты с ИИ приходилось и раньше, опыт разный и не однозначный, но этот случай уникален тем, что ИИ со второй(!) попытки выдал работоспособный скрипт, который выгрузил всю информацию о товарах в csv.
Копируем скрипт, запускаем его у себя и получаем спустя время результат.
Все товары сохранились в csv:
Результат потрясающий. Полученный файл мы сможем без проблем загрузить в Прайсматрикс для дальнейшей обработки. И Прайсматрикс не нужно дорабатывать, чтобы грузить с этого api 🙂
Код самого скрипта, можно пользоваться:
import csv
import json
import re
import time
from typing import Dict, Any, List, Iterable
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
PRICELIST_URL = "https://svarog-rf.ru/api/pricelist"
PRODUCT_URL_TMPL = "https://svarog-rf.ru/api/products/{num}"
OUTPUT_CSV = "products.csv"
# --- сетап сессии с ретраями и таймаутами ---
def make_session() -> requests.Session:
s = requests.Session()
retries = Retry(
total=5,
backoff_factor=0.5,
status_forcelist=(429, 500, 502, 503, 504),
allowed_methods=frozenset(["GET"]),
raise_on_status=False,
)
s.headers.update({"User-Agent": "svarog-export-bot/1.0"})
s.mount("https://", HTTPAdapter(max_retries=retries))
s.mount("http://", HTTPAdapter(max_retries=retries))
return s
def sanitize_for_col(name: str) -> str:
"""Нормализуем заголовок колонки: пробелы -> _, убираем лишние символы."""
if name is None:
return ""
name = name.strip()
name = re.sub(r"\s+", "_", name)
name = re.sub(r"[^\w\-.:А-Яа-яЁё]", "_", name) # позволим кириллицу и цифры
return name
def join_list(values: Iterable[Any]) -> str:
return "|".join(map(lambda v: str(v).strip(), values)) if values else ""
def fetch_pricelist(session: requests.Session) -> List[Dict[str, Any]]:
resp = session.get(PRICELIST_URL, timeout=30)
resp.raise_for_status()
data = resp.json()
if not isinstance(data, list):
raise ValueError("Ожидался список от /api/pricelist")
return data
def fetch_product(session: requests.Session, num: str) -> Dict[str, Any]:
url = PRODUCT_URL_TMPL.format(num=num)
r = session.get(url, timeout=30)
if r.status_code == 404:
# товар отсутствует (например, временно исключён)
return {}
r.raise_for_status()
return r.json()
def flatten_product(p: Dict[str, Any]) -> Dict[str, Any]:
"""Плоская строка CSV из полной карточки товара."""
row: Dict[str, Any] = {}
# Базовые поля
for key in [
"num", "title", "category", "rr_price", "ma_price",
"in_stock", "outdated", "warranty", "url",
"description", "including", "spec_id"
]:
row[key] = p.get(key, "")
# Ярлыки
labels = p.get("labels") or []
row["labels"] = join_list(labels)
# Изображения
images = p.get("images") or []
row["images_count"] = len(images)
row["image_urls"] = join_list(img.get("url", "") for img in images)
row["image_titles"] = join_list(img.get("title", "") for img in images)
row["image_sizes"] = join_list(
f'{img.get("width","")}x{img.get("height","")}:{img.get("filesize","")}'
for img in images
)
# Документы
docs = p.get("documents") or []
row["documents_count"] = len(docs)
row["document_urls"] = join_list(doc.get("url", "") for doc in docs)
row["document_titles"] = join_list(doc.get("title", "") for doc in docs)
row["document_categories"] = join_list(doc.get("category", "") for doc in docs)
# Характеристики — и сводка, и по-колоночно с id
specs = p.get("spec_fields") or []
spec_summaries = []
for sf in specs:
title = sf.get("title", "")
units = sf.get("units") or ""
values = sf.get("value") or []
val_joined = ", ".join(map(str, values))
# сводная строка
spec_summaries.append(f"{title}: {val_joined}{(' ' + units) if units else ''}")
# колонка по id (стабильно) + названием (для удобства)
sid = sf.get("id")
if sid is not None:
col = f"spec_{sid}__{sanitize_for_col(title)}"
else:
col = f"spec__{sanitize_for_col(title)}"
row[col] = val_joined if not units else f"{val_joined} {units}"
row["specs"] = "; ".join(spec_summaries)
return row
def collect_all_columns(rows: List[Dict[str, Any]]) -> List[str]:
cols = []
seen = set()
# хотим стабильный порядок: базовые поля сначала
base_order = [
"num", "title", "category", "rr_price", "ma_price",
"in_stock", "outdated", "warranty", "labels",
"url", "description", "including",
"images_count", "image_urls", "image_titles", "image_sizes",
"documents_count", "document_urls", "document_titles", "document_categories",
"spec_id", "specs",
]
for c in base_order:
if c not in seen:
cols.append(c); seen.add(c)
# затем динамические spec_* и прочие поля, появившиеся у некоторых товаров
for row in rows:
for k in row.keys():
if k not in seen:
cols.append(k); seen.add(k)
return cols
def main():
session = make_session()
print("1) Загружаю прайс-лист…")
pricelist = fetch_pricelist(session)
nums = [item.get("num") for item in pricelist if item.get("num")]
print(f"Найдено товаров в прайс-листе: {len(nums)}")
rows: List[Dict[str, Any]] = []
for i, num in enumerate(nums, start=1):
try:
p = fetch_product(session, num)
if not p:
print(f"[{i}/{len(nums)}] {num}: нет данных (404)")
continue
row = flatten_product(p)
rows.append(row)
if i % 25 == 0:
print(f"[{i}/{len(nums)}] обработано…")
time.sleep(0.05) # деликатная пауза
except Exception as e:
print(f"[{i}/{len(nums)}] {num}: ошибка {e}")
if not rows:
print("Не удалось собрать данные карточек товаров.")
return
columns = collect_all_columns(rows)
print(f"2) Сохраняю в CSV ({OUTPUT_CSV})…")
# utf-8-sig — удобнее для Excel
with open(OUTPUT_CSV, "w", newline="", encoding="utf-8-sig") as f:
writer = csv.DictWriter(f, fieldnames=columns, extrasaction="ignore")
writer.writeheader()
for r in rows:
writer.writerow(r)
print(f"Готово: {len(rows)} товаров сохранено в {OUTPUT_CSV}")
if __name__ == "__main__":
main()
Или скачать можно по ссылке в текстовом файле: https://storage.catalogloader.com/screenshots/saa/2025-08-19-174245744--A10094I0pbO62K0N11009.txt


