Промышленный экспорт собранных данных: CSV, JSON и REST API
Спарсенные данные редко нужны в сыром виде. Аналитик просит CSV для сводной таблицы, разработчик — JSON с возможностью фильтрации, а система учёта — автоматические уведомления через webhook. Типичная ситуация: парсер собрал 50 000 товаров, а отдавать их одним файлом нельзя — сервер падает по памяти, Excel не открывает. Мы решаем это потоковой передачей и грамотным API-дизайном. Потоковый CSV обрабатывает данные в 10 раз быстрее, чем загрузка всего файла в память, и позволяет экспортировать каталоги до 500 000 строк без сбоев. Стриминг снижает нагрузку на сервер в 10 раз, а значит — экономит до 50% затрат на серверную инфраструктуру. Свяжитесь с нами для подбора оптимального формата экспорта под вашу задачу.
Сырые данные часто содержат дубликаты, невалидные записи и мусор. Перед экспортом мы выполняем очистку и нормализацию, чтобы на выходе были только качественные данные. За годы практики мы реализовали более 50 интеграций экспорта для проектов с миллионами записей.
Как построить отказоустойчивый экспорт для миллионов записей?
Для больших объёмов данных критична архитектура экспорта. Мы используем курсоры базы данных, чанкованные запросы с пагинацией и backpressure-контроль. В реляционных БД (PostgreSQL, MySQL) применяем server-side cursors — это позволяет не загружать весь результат в память. Для NoSQL (MongoDB) используем allowDiskUse() и итераторы. Типовой шаблон: читаем по 1000 записей, порционно отправляем в стрим. Если клиент медленный — приостанавливаем чтение, чтобы не забить память.
Потоковый экспорт CSV для больших объёмов
Для CSV с объёмом более 10 000 строк не генерируем весь файл в памяти — используем стриминг. Пример на Flask с Response и stream_with_context:
import csv import io from flask import Response, stream_with_context def export_csv(site_id: int, filters: dict): def generate(): output = io.StringIO() writer = csv.DictWriter(output, fieldnames=[ 'id', 'name', 'price', 'currency', 'url', 'in_stock', 'scraped_at' ]) writer.writeheader() yield output.getvalue() output.truncate(0); output.seek(0) for product in stream_products(site_id, filters): writer.writerow(product) yield output.getvalue() output.truncate(0); output.seek(0) return Response( stream_with_context(generate()), mimetype='text/csv', headers={'Content-Disposition': 'attachment; filename=export.csv'}, ) Такой подход позволяет обрабатывать файлы любого размера без увеличения потребления памяти. Мы применяем его в проектах с каталогами на 200 000+ позиций — гарантируем стабильную работу под нагрузкой.
Почему webhook с подписью HMAC безопаснее простого POST?
Отправка данных по webhook без проверки подлинности — уязвимость: любой может сэмитировать запрос в вашу систему. Мы добавляем подпись через HMAC-SHA256, чтобы получатель верифицировал отправителя. Используем httpx:
import httpx, hashlib, hmac def send_webhook(url: str, secret: str, payload: dict): body = json.dumps(payload).encode() sig = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest() httpx.post(url, content=body, headers={ 'Content-Type': 'application/json', 'X-Signature-SHA256': f'sha256={sig}', }, timeout=10) Идентичный secret хранится у отправителя и получателя — это исключает подделку запросов. Подпись вычисляется из тела, поэтому любое изменение данных сломает проверку. Для критичных данных можно добавить шифрование тела запроса по алгоритму AES.
Сравнение форматов экспорта
| Характеристика | CSV (стриминг) | JSON API | Webhook |
|---|---|---|---|
| Назначение | Отчёты, аналитика | Интеграция систем | Триггеры, оповещения |
| Объём данных | Любой (поток) | До 10 000 записей на страницу | Один event |
| Безопасность | Базовая аутентификация | API-ключ + rate-limit | HMAC-подпись |
| Сложность разработки | 1 день | 1–2 дня | 2–3 дня (с фильтрами) |
| Гибкость | Фиксированные поля | Выбор полей, пагинация | Кастомный payload |
Как фильтровать данные в REST API?
REST API для спарсенных данных реализуем с полноценной фильтрацией, пагинацией и выбором полей. Пример эндпоинта:
GET /api/v1/scraped-products?site_id=7&in_stock=true&fields=name,price,url&page=1&per_page=100 Ответ:
{ "data": [ { "name": "Кроссовки Nike Air Max", "price": 89.99, "url": "https://..." } ], "meta": { "page": 1, "per_page": 100, "total": 4823 } } Аутентификация — API-ключ в заголовке X-API-Key. Доступ ограничивается по IP и rate-limit (100 запросов/мин). Поддерживается сортировка по любому полю, а также агрегация (сумма, среднее) для аналитических запросов.
Какие сценарии использования экспорта?
| Формат | Когда использовать | Пример |
|---|---|---|
| CSV | Аналитика, отчёты, загрузка в Excel | Товарный каталог 200 000 строк |
| JSON API | Интеграция с внутренними системами | Получение данных по API в real-time |
| Webhook | Автоматизация уведомлений | Оповещение о появлении нового товара |
Что входит в типовую реализацию (deliverables)
- Исходный код экспорта с комментариями
- Документация API в формате OpenAPI (Swagger)
- Скрипты для развёртывания (Docker, docker-compose)
- Примеры интеграции на Python и JavaScript
- Поддержка в течение 30 дней после сдачи
- Возможность интеграции с Sentry для мониторинга ошибок
Сроки и стоимость реализации
Базовая реализация CSV и JSON API с аутентификацией — 1–2 рабочих дня. Добавление webhook с подписью, фильтры и выбор полей — ещё 1 день. Стоимость рассчитывается индивидуально после анализа задачи. Свяжитесь с нами, чтобы обсудить детали. Закажите реализацию экспорта под ключ — получите работающее решение за 2–3 дня.







