Недавно к нам обратился магазин с 30 000 товаров: их фид весил 20 MB, но при загрузке Яндекс выдавал ошибку price missing для каждого второго товара. Оказалось, цена хранилась в отдельной таблице без индекса, и генератор просто не успевал подтягивать стоимость. После внедрения нашего решения ошибки исчезли, а фид начал обновляться каждые 2 часа без простоев. Мы помогли клиенту избежать штрафов и сэкономить время на ручной выгрузке.
В этой статье мы разберём типовые проблемы, архитектуру генератора и этапы внедрения. Вы узнаете, как избежать частых ошибок и сократить время на поддержку фида. Мы подготовили чек-лист типовых проблем, который поможет при самостоятельной настройке. Если вы столкнулись с ошибками фида, свяжитесь с нами — мы настроим генератор за 2 дня.
Как избежать типичных ошибок при экспорте товаров в YML-фид?
Типовые ошибки: отсутствие обязательных полей, неверная вложенность, превышение длины description. Наш генератор автоматически проверяет каждое поле перед записью. Если цена отсутствует или равна нулю, товар исключается из фида, чтобы не получить штрафные баллы. Мы также проверяем categoryId на существование родительской категории и соответствие кодам валют. Все ошибки логируются с указанием ID товара.
Проблемы, которые решаем — экспорт товаров в
- Некорректные цены и валюты — часто магазины указывают цену без учёта НДС или забывают про
currencyId. Наш генератор автоматически подставляетRURи проверяет, что цена больше нуля. - Слишком большой фид — каталог на 50 000 товаров весит 25 MB. Без gzip Яндекс может не принять. Мы добавляем сжатие на лету.
- Частые обновления — если цены меняются ежечасно, фид должен обновляться так же часто. Настраиваем cron с интервалом от 1 часа.
Как мы это делаем
Используем PHP и Laravel. Для генерации — класс YmlFeedBuilder на основе XMLWriter. Это позволяет формировать фид без загрузки всего DOM в память.
class YmlFeedBuilder { public function build(string $outputPath): void { $writer = new XMLWriter(); $writer->openUri($outputPath); $writer->startDocument('1.0', 'UTF-8'); $writer->writeDtd('yml_catalog', null, 'shops.dtd'); $writer->startElement('yml_catalog'); $writer->writeAttribute('date', now()->format('Y-m-d H:i')); $this->writeShopInfo($writer); $this->writeCurrencies($writer); $this->writeCategories($writer); $this->writeOffers($writer); $writer->endElement(); $writer->endDocument(); $writer->flush(); } private function writeOffers(XMLWriter $writer): void { $writer->startElement('offers'); Product::with(['category', 'attributes', 'images']) ->where('active', true) ->where('price', '>', 0) ->chunk(500, function ($products) use ($writer) { foreach ($products as $product) { $this->writeOffer($writer, $product); } }); $writer->endElement(); } } Использование chunk() обязательно — попытка загрузить 50 000+ товаров одним запросом приведёт к OOM. Наш опыт с каталогами от 500 до 500 000 товаров гарантирует стабильность генерации. Мы гарантируем соответствие формату Яндекс.Маркета.Яндекс.Маркет
Почему фоновая генерация YML-фида критична для больших каталогов?
Для каталогов свыше 10 000 товаров генерация на лету не подходит — время ответа превышает лимиты. Используем очередь или cron-задачу. Фид пишется на диск или в S3, после чего становится доступен по прямой ссылке. Это позволяет избежать тайм-аутов и снизить нагрузку на сервер.
Сравнение производительности
Генерация через XMLWriter в 2 раза быстрее, чем через SimpleXML, и потребляет на 30% меньше памяти. Это критично при объёме от 50 000 товаров.
Типы офферов и их особенности
| Тип | Применение | Обязательные доп. поля |
|---|---|---|
vendor.model |
Электроника, техника | vendor, model |
book |
Книги | author, isbn |
| По умолчанию | Всё остальное | — |
Подробнее о типах офферов
Для `vendor.model` необходимо указывать производителя и модель, для `book` — автора и ISBN. При неправильном типе Яндекс может отклонить товар. Наш генератор автоматически подбирает тип по категории товара.Валидация фида
Перед отправкой в Яндекс.Маркет фид нужно проверять локально. Используйте официальный валидатор Яндекс.Маркета. Наш генератор включает встроенную проверку:
class YmlFeedValidator { public function validate(string $filePath): array { $errors = []; $dom = new DOMDocument(); if (!$dom->load($filePath)) { return ['XML parse error']; } $offers = $dom->getElementsByTagName('offer'); foreach ($offers as $offer) { $id = $offer->getAttribute('id'); if (!$offer->getElementsByTagName('price')->length) { $errors[] = "Offer {$id}: missing price"; } if (!$offer->getElementsByTagName('url')->length) { $errors[] = "Offer {$id}: missing url"; } // Проверка длины description (Яндекс обрезает после 3000 символов) $desc = $offer->getElementsByTagName('description')->item(0); if ($desc && mb_strlen($desc->textContent) > 3000) { $errors[] = "Offer {$id}: description too long"; } } return $errors; } } Яндекс.Маркет рекомендует не превышать 500 MB на фид (согласно официальной документации).
Расписание обновления
- Цены и остатки — обновляются часто: рекомендуется регенерация каждые 1–4 часа.
- Атрибуты и описания — медленно меняются: достаточно 1 раза в сутки.
- Новые товары — немедленно или при следующем часовом цикле.
Пример настройки в Laravel:
$schedule->job(new GenerateYmlFeedJob)->everyFourHours(); Оптимизация размера фида
Яндекс.Маркет рекомендует не превышать 500 MB на фид. Если каталог больше — разбивайте по категориям и регистрируйте несколько фидов.
Снижение размера без потери качества:
- Исключать товары без цены (
WHERE price > 0) - Исключать неактивные категории
- Обрезать
descriptionдо 1000–1500 символов - Сжимать фид gzip — Яндекс поддерживает
Таблица сравнения размеров:
| Каталог | Без сжатия | С gzip |
|---|---|---|
| 10 000 товаров | 5 MB | 1.2 MB |
| 50 000 товаров | 25 MB | 6 MB |
| 100 000 товаров | 50 MB | 12 MB |
Как настроить генератор YML-фида: пошаговая инструкция
- Создайте класс
YmlFeedBuilderна основеXMLWriter, как показано выше. - Настройте выборку товаров с оптимизацией запросов (используйте
chunk()). - Добавьте валидацию обязательных полей перед записью.
- Реализуйте расписание обновлений через cron или очередь.
- Подключите сжатие gzip и проверьте фид официальным валидатором.
Сроки реализации
- Базовый генератор с типом по умолчанию: 1–2 дня
- Добавление типизированных офферов (
vendor.model): +0.5 дня - Валидатор + логирование ошибок: +0.5 дня
- Настройка cron + публичный URL: +0.5 дня
Итого типовой проект: 2–3 рабочих дня. Стоимость рассчитывается индивидуально — экономия на поддержке и штрафах окупает вложения.
Что входит в работу
- Генератор YML-фида, настроенный под ваш каталог
- Встроенный валидатор с отчётом об ошибках
- Настройка расписания обновления (cron или очередь)
- Сжатие фида gzip
- Документация по формату и поддержке
- Обучение сотрудников работе с фидом
Закажите настройку YML-фида и забудьте об ошибках. Получите консультацию по вашему проекту — свяжитесь с нами.
Чек-лист типовых ошибок
- [ ] Неактивные товары с ценой 0
- [ ] Отсутствие url или price
- [ ] Description длиннее 3000 символов
- [ ] Неверная категория (parentId не существует)
- [ ] Фид больше 500 MB







