Реализация экспорта товаров из сайта в YML-фид

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Реализация экспорта товаров из сайта в YML-фид
Средняя
~3-5 рабочих дней
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Реализация экспорта товаров из сайта в YML-фид

YML (Yandex Market Language) — XML-формат, который Яндекс.Маркет требует для загрузки каталога. Правильно сформированный фид обеспечивает индексацию без ошибок, корректное отображение офферов и допуск к платным размещениям. Неправильный фид — это отклонённые товары, штрафные баллы магазина и выпадение из поиска.

Структура YML и требования Яндекс.Маркета

Формат описан в официальной документации. Минимальная структура:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE yml_catalog SYSTEM "shops.dtd">
<yml_catalog date="2024-01-15 10:00">
  <shop>
    <name>Мой магазин</name>
    <company>ООО Компания</company>
    <url>https://example.com</url>
    <currencies>
      <currency id="RUR" rate="1"/>
    </currencies>
    <categories>
      <category id="10">Электроника</category>
      <category id="11" parentId="10">Смартфоны</category>
    </categories>
    <offers>
      <offer id="12345" available="true">
        <url>https://example.com/product/12345</url>
        <price>29990</price>
        <currencyId>RUR</currencyId>
        <categoryId>11</categoryId>
        <picture>https://example.com/img/12345.jpg</picture>
        <name>Смартфон Samsung Galaxy S24</name>
        <vendor>Samsung</vendor>
        <description>...</description>
        <param name="Цвет">Чёрный</param>
        <param name="Память">256 GB</param>
      </offer>
    </offers>
  </shop>
</yml_catalog>

Критичные поля для допуска к размещению: url, price, currencyId, categoryId, name. Поле available влияет на отображение — товары с false исключаются из поиска, но сохраняются в истории цен.

Архитектура генератора фида

Для небольших каталогов (до 10 000 товаров) фид можно генерировать на лету. Для крупных — только через фоновую задачу с записью на диск или в CDN.

Схема работы:

Cron/Queue → Builder → XML Writer → Storage (disk/S3) → Public URL

Реализация на PHP (Laravel):

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.

Типы офферов

Яндекс.Маркет различает несколько типов, каждый с обязательными полями:

Тип Применение Обязательные доп. поля
vendor.model Электроника, техника vendor, model
book Книги author, isbn
audiobook Аудиокниги author, publisher
medicine Лекарства vendor, registration-number
artist.title Музыка, кино artist, title
tour Туры worldRegion, country
По умолчанию Всё остальное

Для большинства интернет-магазинов работает vendor.model или тип по умолчанию.

Валидация фида

Перед отправкой в Яндекс.Маркет фид нужно проверять локально. Используйте Feed Validator или схему shops.dtd.

Собственная валидация на этапе сборки:

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;
    }
}

Расписание обновления

Частота зависит от динамики каталога:

  • Цены и остатки — обновляются часто: рекомендуется регенерация каждые 1–4 часа
  • Атрибуты и описания — медленно меняются: достаточно 1 раза в сутки
  • Новые товары — немедленно или при следующем часовом цикле

Пример расписания в Laravel (app/Console/Kernel.php):

$schedule->job(new GenerateYmlFeedJob)->everyFourHours();

Оптимизация размера фида

Яндекс.Маркет рекомендует не превышать 500 MB на фид. Если каталог больше — разбивайте по категориям и регистрируйте несколько фидов в личном кабинете.

Снижение размера без потери качества:

  • Исключать товары без цены (WHERE price > 0)
  • Исключать неактивные категории
  • Обрезать description до 1000–1500 символов
  • Сжимать фид gzip (Content-Encoding: gzip) — Яндекс поддерживает
// Сжатие готового фида
$source = storage_path('app/public/feed.xml');
$compressed = storage_path('app/public/feed.xml.gz');

$fp = gzopen($compressed, 'w9');
gzwrite($fp, file_get_contents($source));
gzclose($fp);

Сроки реализации

  • Базовый генератор с типом по умолчанию: 1–2 дня
  • Добавление типизированных офферов (vendor.model): +0.5 дня
  • Валидатор + логирование ошибок: +0.5 дня
  • Настройка cron + публичный URL: +0.5 дня

Итого типовой проект: 2–3 рабочих дня.