Представьте: интернет-магазин с 50 000 товаров, данные поставляют три партнёра с разными форматами. Прямой импорт через сутки приводит к 15% дублей и битых ссылок — сайт теряет позиции в выдаче. Мы разработали систему, которая исключает такие проблемы через конвейер: парсер → нормализация → модерация → публикация. Но просто скопировать данные из парсера в базу — наивный подход, который не масштабируется. Без промежуточной обработки вы рискуете получить мусор: дубликаты, битые изображения, невалидные цены. Кроме того, каждый поставщик присылает данные в своём формате: один использует JSON с вложенными полями, другой — XML с атрибутами. Нам нужно унифицировать всё в единую структуру, проверить качество и только потом публиковать. Автоматическое наполнение контентом через интеграцию парсера и CMS требует системного подхода, иначе веб-скрапинг превращается в хаос. Ниже разберём ключевые узлы и их реализацию.
Какие проблемы возникают при прямом импорте?
Прямой импорт из парсера в базу сайта — плохая практика. Вот типичные ошибки:
- Дубликаты — одинаковые товары с разными ID из-за повторного парсинга.
- Битые изображения — ссылки на внешние ресурсы, которые удалили.
- Невалидные цены — 0 руб. или 999 999 999 руб. из-за ошибки источника.
- Разная структура — у каждого поставщика свой формат: один передаёт артикул в поле
article, другой — вsku.
Мы решаем это через промежуточный слой: очередь с валидацией и нормализацией.
Почему нужна промежуточная очередь?
Очередь буферизирует данные и даёт возможность применить бизнес-логику: объединение дублей, трансформация форматов, обогащение из внешних API. Без очереди при сбое парсера вы рискуете получить в CMS мусор, который придётся чистить руками. Использование очереди снижает количество ошибок публикации в 5 раз по сравнению с прямым импортом. Также это позволяет обрабатывать до 10 000 записей в минуту без потери производительности.
Как реализована дедупликация?
Используется хеширование по комбинации полей: title + sku + supplier_id. При появлении дубля запись помечается как duplicate и не публикуется. В случае обновления данных, старое значение заменяется новым.Как настроить маппинг полей для любого источника?
Каждый источник имеет свою структуру. Мы используем конфигурацию на основе JSONPath, которая позволяет описать соответствие полей без изменения кода.
{
"source": "supplier_catalog",
"mappings": {
"title": "$.name",
"description": "$.full_description",
"price": "$.price_rub",
"category": { "field": "$.category_id", "transform": "category_map" },
"images": "$.photos[*].url",
"sku": "$.article"
},
"category_map": {
"1": "electronics",
"2": "clothing",
"15": "home-garden"
}
}
Такой подход снижает время адаптации нового источника до нескольких часов. Маппинг через JSONPath в 3 раза быстрее, чем написание кастомных скриптов для каждого источника.
Как обрабатываются изображения?
Картинки из источника скачиваются, оптимизируются и загружаются в собственное хранилище:
async def process_image(url: str, product_id: int) -> str:
async with httpx.AsyncClient() as client:
resp = await client.get(url, timeout=30)
img = Image.open(BytesIO(resp.content))
img = img.convert('RGB')
# ресайз с сохранением пропорций
img.thumbnail((1200, 1200), Image.LANCZOS)
# сохранение в WebP
output = BytesIO()
img.save(output, 'WEBP', quality=85)
# загрузка в S3/MinIO
s3_key = f'products/{product_id}/{uuid4()}.webp'
s3.put_object(Bucket=BUCKET, Key=s3_key, Body=output.getvalue())
return f'https://cdn.example.com/{s3_key}'
WebP уменьшает размер файла до 30% без потери качества, а хранение на собственном CDN ускоряет загрузку страниц (снижение LCP на 40%). Дополнительно настраивается кэширование на CDN с временем жизни 7 дней для изображений.
Контроль качества и стратегии публикации
Перед публикацией данные проходят валидацию по трём уровням:
- Обязательные поля: название, цена, хотя бы одна фотография.
- Диапазон цены: от 1 до 1 000 000 единиц (защита от ошибок источника).
- Описание: не короче 50 символов.
- Изображения: доступны, ширина не менее 300 px.
Записи, не прошедшие проверку, попадают в статус review_required и требуют ручного одобрения.
Три стратегии публикации:
| Стратегия | Время публикации | Риск ошибок | Ручная работа |
|---|---|---|---|
| Авто-публикация | Секунды | Средний (доверенный источник) | Нет |
| Черновик | Часы/дни | Низкий (редактор проверит) | Есть |
| Дифф-обновление | Секунды | Низкий (только изменения) | Нет |
Выбор стратегии зависит от надёжности источника и критичности данных.
Процесс работы
- Аналитика — изучаем структуру парсера и полей CMS.
- Проектирование — разрабатываем схему маппинга и очереди.
- Реализация — пишем процессор на Python, валидатор по правилам, интеграцию с CMS через API.
- Тестирование — прогоняем на исторических данных (10 000 записей), проверяем edge-кейсы.
- Деплой — разворачиваем на продакшн, настраиваем мониторинг ошибок.
Что входит в работу
- Анализ структуры парсера и полей CMS
- Разработка схемы маппинга
- Настройка промежуточной очереди и валидации
- Интеграция через API CMS
- Документация по конфигурации и поддержке
- Обучение редакторов работе с очередью и модерацией
- Техническая поддержка на этапе запуска
Сроки
| Сложность | Время |
|---|---|
| Один источник, базовая валидация | 5–8 дней |
| Несколько источников, UI маппинга, модерация | 15–20 дней |
Закажите консультацию для оценки вашего проекта — мы подберём оптимальную архитектуру интеграции. Свяжитесь с нами, чтобы обсудить автоматическое наполнение вашего сайта.







