Импорт товаров из YML: потоковый парсинг и маппинг

Потоковый парсинг и маппинг YML-фидов Яндекс.Маркет

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

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

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

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Импорт товаров из YML: потоковый парсинг и маппинг
Средний
~3-5 дней

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

Часто задаваемые вопросы

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

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

Потоковый парсинг и маппинг YML-фидов Яндекс.Маркет

Каждый день тысячи товаров загружаются в каталоги, но ручной импорт из YML-фидов — головная боль. PHP-скрипт падает по памяти на файлах от 500 МБ, категории не совпадают, а устаревшие цены остаются в системе. Мы решаем эти задачи с помощью потокового парсинга на XMLReader и интеллектуального маппинга категорий. Наша разработка автоматизирует импорт товаров из YML, сокращая ручной труд на 90% и экономя до полумиллиона рублей в год. Опыт внедрения в десятках проектов подтверждает: потоковый парсинг YML устраняет узкие места. Мы гарантируем стабильную работу парсинга на любых объёмах данных.

Как потоковый парсер справляется с фидами до 2 ГБ?

YML-фиды от крупных поставщиков часто превышают 500 МБ. Использование SimpleXML::load() приводит к переполнению памяти и краху скрипта. Мы применяем потоковый парсер XMLReader, который обрабатывает документ по узлам, не загружая весь файл в память. Импорт через XMLReader работает в 10 раз быстрее при объёмах данных более 100 МБ.

Параметр SimpleXML XMLReader
Потребление RAM на 1 ГБ фида ~1.5 ГБ ~10 МБ
Скорость обработки 500 МБ 120 секунд 45 секунд
Поддержка потоковой обработки Нет Да

Пример реализации потокового парсера:

class YmlFeedParser { public function parse(string $url): iterable { $context = stream_context_create([ 'http' => ['timeout' => 60, 'user_agent' => 'YMLImporter/1.0'], ]); $reader = new \XMLReader(); $reader->open($url, null, LIBXML_NOERROR); // Сначала собираем категории (они в начале файла) $categories = $this->parseCategories($reader); // Затем итерируем offers while ($reader->read()) { if ($reader->nodeType === \XMLReader::ELEMENT && $reader->name === 'offer') { $node = new \SimpleXMLElement($reader->readOuterXml()); yield $this->parseOffer($node, $categories); } } $reader->close(); } private function parseCategories(\XMLReader $reader): array { $cats = []; while ($reader->read()) { if ($reader->nodeType === \XMLReader::ELEMENT && $reader->name === 'category') { $node = new \SimpleXMLElement($reader->readOuterXml()); $id = (string) $node['id']; $cats[$id] = [ 'name' => (string) $node, 'parentId' => (string) ($node['parentId'] ?? ''), ]; } if ($reader->nodeType === \XMLReader::ELEMENT && $reader->name === 'offers') { break; } } return $cats; } private function parseOffer(\SimpleXMLElement $node, array $categories): array { $params = []; foreach ($node->param as $param) { $params[(string) $param['name']] = [ 'value' => (string) $param, 'unit' => (string) ($param['unit'] ?? ''), ]; } $images = []; foreach ($node->picture as $pic) { $images[] = (string) $pic; } $categoryId = (string) $node->categoryId; $categoryPath = $this->buildCategoryPath($categoryId, $categories); return [ 'sku' => (string) $node['id'], 'available' => ((string) $node['available']) === 'true', 'name' => (string) $node->name, 'price' => (float) $node->price, 'old_price' => $node->oldprice ? (float) $node->oldprice : null, 'currency' => (string) $node->currencyId, 'category_id' => $categoryId, 'category_path' => $categoryPath, 'images' => $images, 'vendor' => (string) $node->vendor, 'vendor_code' => (string) $node->vendorCode, 'description' => (string) $node->description, 'params' => $params, 'barcode' => (string) $node->barcode, ]; } private function buildCategoryPath(string $id, array $cats): string { $path = []; $current = $id; while ($current && isset($cats[$current])) { array_unshift($path, $cats[$current]['name']); $current = $cats[$current]['parentId']; } return implode(' > ', $path); } } 

Почему потоковый парсинг лучше SimpleXML?

SimpleXML загружает весь XML в дерево DOM, потребляя ~1.5 ГБ оперативной памяти на 1 ГБ фида. XMLReader читает документ по одному элементу, используя всего ~10 МБ. Это позволяет обрабатывать фиды любого размера без оверхэда. Разница особенно заметна при работе с YML-файлами от 100 МБ: SimpleXML часто падает с ошибкой памяти, а потоковый парсер завершает импорт за минуты.

Как настроить маппинг категорий под частые обновления?

Маппинг категорий — одна из самых частых проблем. Поставщик может добавить, удалить или переименовать категории, и товары перестанут попадать в нужные разделы вашего магазина. Мы реализуем механизм маппинга с автоматическим обновлением по ключевым словам и fallback-логикой. В вашем каталоге товары всегда окажутся в правильной категории, даже если поставщик изменил структуру. Получите консультацию по настройке маппинга под ваш каталог.

class YmlImportJob implements ShouldQueue { public function handle( YmlFeedParser $parser, YmlCategoryMapper $categoryMapper, ProductImportService $importer, ): void { foreach ($parser->parse($this->source->url) as $offer) { if (!$offer['available']) { $importer->markUnavailable($offer['sku'], $this->source->id); continue; } $siteCategoryId = $categoryMapper->resolve( $offer['category_id'], $offer['category_path'], $this->source->id ); $importer->upsert(array_merge($offer, [ 'site_category_id' => $siteCategoryId, 'source_id' => $this->source->id, ])); } } } 

Типы офферов в YML

YML поддерживает несколько типов: обычный товар, книги, аудио/видео, лекарства, туры. Для стандартного каталога электроники или одежды достаточно типа "обычный товар". В нашей реализации вы можете гибко расширять парсинг под новые типы без изменения базового кода.

Тип Атрибут type Дополнительные поля
Обычный товар (не указан) vendor, model
Книги book author, publisher, ISBN
Аудио/видео audiobook artist, year
Лекарства medicine production-line
Туры tour country, nights

Работа с валютами и конвертация

YML-фиды могут содержать цены в разных валютах с курсами. Мы конвертируем их в рубли по актуальному курсу, в том числе с подтягиванием данных ЦБ. Это позволяет избежать ошибок при импорте мультивалютных фидов.

private function convertToRub(float $price, string $currencyId, array $currencies): float { if ($currencyId === 'RUR' || $currencyId === 'RUB') return $price; $rate = $currencies[$currencyId]['rate'] ?? null; if (!$rate) { $rate = $this->cbRateProvider->getRate($currencyId); } return round($price * $rate, 2); } 

Валидация фида перед импортом

Перед полным импортом мы проверяем корректность XML: соответствие DTD, наличие обязательных элементов. Это предотвращает загрузку битых фидов и экономит время.

class YmlFeedValidator { public function validate(string $url): ValidationResult { $errors = []; libxml_use_internal_errors(true); $dom = new \DOMDocument(); $dom->load($url); $xmlErrors = libxml_get_errors(); libxml_clear_errors(); foreach ($xmlErrors as $error) { $errors[] = "XML error at line {$error->line}: {$error->message}"; } $xpath = new \DOMXPath($dom); if (!$xpath->query('//offers/offer')->length) { $errors[] = 'No offers found in feed'; } return new ValidationResult(empty($errors), $errors); } } 

Расписание и кэширование фида

YML-фиды обновляются с разной периодичностью — от раза в час до раза в сутки. Мы кэшируем скачанную копию на время жизни, чтобы не запрашивать поставщика при каждом запуске. Если фид не изменился — используем кэш, не нагружая ни свой, ни сторонний сервер. Повторная загрузка одних и тех же данных ведёт к неоправданным расходам трафика и времени.

Типичные ошибки при импорте YML

  • Неправильный формат даты/времени в поле expiry.
  • Отсутствие url у товара при использовании Яндекс.Директа.
  • Различия в регистре атрибутов (available="true" vs available="TRUE").
  • Повреждённые XML-сущности (например, неэкранированный амперсанд).

Как внедрить импорт YML: пошаговая инструкция

  1. Анализируем текущий YML-фид: схему, объём, валюты, типы офферов.
  2. Разрабатываем потоковый парсер с XMLReader под ваш стек (Laravel, Symfony и т.д.).
  3. Настраиваем маппинг категорий с автоподбором и fallback-логикой.
  4. Реализуем конвертацию валют, обработку изображений и характеристик.
  5. Добавляем валидацию фида и логирование ошибок.
  6. Интегрируем с вашей существующей архитектурой, тестируем на реальном фиде.
  7. Внедряем кэширование и планировщик для автоматического обновления.
  8. Передаём документацию и проводим обучение.

Что входит в работу

  • Разработка потокового парсера YML под ваш стек.
  • Механизм маппинга категорий с автоподбором.
  • Обработка изображений, характеристик, мультивалют.
  • Валидация фида и логирование ошибок.
  • Интеграция с вашей текущей архитектурой (Laravel, Symfony, любой фреймворк).
  • Тестирование на реальном фиде поставщика.
  • Документация и инструкция по эксплуатации.
  • Гарантия стабильной работы в течение 30 дней после внедрения.

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

  • Потоковый парсер, базовый импорт цен/остатков/описаний — 2 дня.
  • Маппинг категорий, конвертация валют, изображения — +1 день.
  • Валидация, кэширование, scheduler, логирование — +1 день.

Итого: от 3 до 5 дней в зависимости от сложности.

Автоматизация импорта товаров — это просто. Свяжитесь с нами для оценки проекта и получите оптимальное решение. Закажите реализацию импорта YML-фида под ключ. Вы получите стабильное решение, которое ускорит загрузку товаров в 10 раз и сократит ручной труд на 90%. Полный список полей описан в YML.