Категории в YML-фиде: как найти ошибки categoryId и parentId

6 минут чтения 0 просмотров
Связь товара с категорией по categoryId: для значения 25 категория не найдена

YML-фид может быть корректным XML, но содержать неправильные связи товаров с категориями. Например, у смартфона указан categoryId, которого нет в справочнике. Или категория существует, но её родитель потерялся при выгрузке.

Проверять нужно две части файла: categoryId внутри товара и отдельный блок categories. Ниже — как сопоставить их, найти сломанную ветку и проверить большой каталог без ручного чтения тысяч предложений.

categoryId — ссылка на идентификатор категории магазина. Его берут из того же справочника, из которого генератор формирует categories: например, из таблицы разделов CMS. Это не название раздела и не автоматически выданный Яндексом номер.

Внутри shop связь выглядит так. Это фрагмент: остальные поля товара опущены.

<categories>
  <category id="1">Электроника</category>
  <category id="10" parentId="1">Смартфоны</category>
</categories>
<offers>
  <offer id="123">
    <name>Смартфон, 128 ГБ</name>
    <categoryId>10</categoryId>
  </offer>
</offers>

Товар 123 ссылается на категорию 10 — «Смартфоны». Её parentId="1" ведёт к «Электронике». У корневой категории родителя нет. Элементы category при этом лежат рядом: вложенность разделов задаёт атрибут parentId, а не вложенные XML-теги.

Товар с categoryId 10 связан со Смартфонами и родительской Электроникой; для categoryId 99 категории нет
Проверяем две ссылки: от товара к категории и от категории к родителю.

Какие правила действуют у сервисов Яндекса

Для товарного YML в Яндекс Директе обязателен ровно один categoryId в каждом offer: положительное целое число длиной до 18 знаков. Блок categories размещают перед offers. Если товар состоит в нескольких разделах CMS, генератору нужно выбрать одну категорию для этой выгрузки. Остальные поля разобраны в статье про YML-фид для Директа.

В Яндекс Товарах categoryId также обязателен и указывает на запись в categories. Справка по категориям требует уникальных названий и ID; идентификаторы — положительные целые числа до 18 символов, без начального нуля. Для распределения в Поиске учитываются названия всей цепочки родителей. Ограничение «один categoryId» прямо сформулировано в справке Директа; не переносите его молча на другие форматы.

У Маркета набор обязательных блоков зависит от задачи: categories нужен для управления товарами, но не для отдельной выгрузки параметров размещения. ID категорий уникальны, числовые, положительные, до 18 цифр и без ведущего нуля; иерархию задаёт parentId. В текущей инструкции по параметрам товара категория передаётся через market_category_id. Поэтому обязательность categoryId из Директа нельзя объявлять общим правилом любого YML для Маркета.

categoryId есть, а категории нет

Допустим, у товара стоит <categoryId>57</categoryId>, но в categories объявлены только разделы 1 и 10. Ссылка ведёт в пустоту. Совпадение числа с ID другой сущности, например товара, ничего не исправляет: нужна именно запись category.

Обычно причина находится в генераторе: категорию удалили из CMS, а старые привязки остались; товары и разделы выбрали из разных наборов данных; фильтр исключил раздел, но сохранил его товары. Сверяйте обе части одной сохранённой версии фида — два скачивания могут попасть на разные генерации.

Восстановите пропущенную категорию, если она должна выгружаться, либо переназначьте товары на правильный существующий раздел в источнике. Не подставляйте всем ошибочным товарам первую доступную категорию: проверка существования пройдёт, а привязка останется неверной. Конкретный результат обработки такой ошибки смотрите в отчёте получателя.

parentId ссылается на отсутствующего родителя

<category id="52" parentId="10">Ноутбуки</category>

Если записи id="10" нет, «Ноутбуки» существуют, но путь обрывается: «? → Ноутбуки» вместо «Электроника → Компьютеры → Ноутбуки». При выборочной выгрузке легко оставить только разделы с товарами и потерять промежуточные категории без собственных предложений.

Включите нужных предков в справочник. Убирать parentId стоит лишь тогда, когда раздел действительно должен стать корневым. Отдельно проверьте самоссылку id="52" parentId="52" и цикл: категория 10 ссылается на 52, а 52 — обратно на 10. Все ID могут существовать, но такая цепочка не заканчивается корнем.

Дубли ID и привязка по названию

<category id="10">Смартфоны</category>
<category id="10">Ноутбуки</category>

У одного ID два значения. По categoryId=10 уже нельзя однозначно определить раздел. Не рассчитывайте, что площадка выберет нужную запись. Исправьте повтор в источнике или таблице соответствий генератора и обновите ссылки затронутых товаров.

Название тоже не заменяет ID. Если «Смартфоны» переименовали в «Телефоны и смартфоны», связь продолжает строиться по числу 10. При простом переименовании удобнее сохранить прежний идентификатор. Если номер всё же меняется, согласованно измените categoryId товаров и parentId дочерних разделов.

Бывает и тихая ошибка: все ссылки существуют, но смартфон привязан к «Ноутбукам». Сравните назначение в CMS, таблицу соответствий и полную цепочку названий в XML. Проверка существования ID сама по себе не определяет, подходит ли раздел товару.

Как проверить категории в большом фиде

Файл на 80 МБ удобнее обработать потоковым XML-парсером, например XMLReader в PHP. Для проверки связей не нужны описания, цены и картинки. Алгоритм такой:

  1. Соберите category/@id и пары id → parentId только из shop/categories. При добавлении отмечайте дубли: обычный словарь может незаметно перезаписать предыдущую запись.
  2. Пройдите shop/offers/offer. Для каждого categoryId проверьте наличие в справочнике. Сохраните ID проблемного товара и значение ссылки.
  3. Отдельно посчитайте отсутствующие и пустые categoryId; проверяйте обязательность и количество элементов по выбранному формату.
  4. Сверьте все непустые parentId со справочником. Затем пройдите цепочки родителей, отмечая посещённые ID внутри каждой цепочки: повтор означает цикл.
  5. Выведите количество ошибок и несколько конкретных примеров каждого вида, чтобы разработчик мог найти исходные записи.

Если справочник ещё не собран, отложите сверку ссылок до конца чтения или сделайте два потоковых прохода. Освобождайте прочитанные элементы; храните только справочник, счётчики и ограниченную выборку ошибок. Если даже категории не помещаются в память, индекс ID и связи родителей можно держать во временной SQLite-базе.

Условная сводка: 184 категории, 12 430 товаров, 7 товаров с неизвестным categoryId, 2 категории с отсутствующим родителем. Это пример диагностики, а не результат реальной проверки. Различайте число затронутых товаров и число неизвестных ID: на один потерянный раздел могут ссылаться сотни предложений.

В полной проверке ФидСторожа реализован поиск неизвестных ссылок categoryId, дублей ID категорий, отсутствующих родителей, самоссылок и циклов. Сервис показывает найденные ошибки; смысловую правильность назначения товара разделу нужно проверить по каталогу.

Если ошибка только у части товаров

Возьмите рабочий и проблемный offer из одного фида. Сравните их categoryId, соответствующие записи category и пути к корню. Общий отсутствующий родитель у проблемных товаров указывает на одну сломанную ветку, а разные неверные ID — на привязки или преобразование идентификаторов.

Если связи исправны, переходите к диагностике пропавших товаров. Ошибки других полей и общий порядок проверки собраны в разборе частых ошибок YML.

Быстрый чек-лист

  • Обязательный categoryId заполнен.
  • Каждая ссылка ведёт в categories.
  • ID категорий уникальны.
  • Все указанные родители существуют.
  • Нет самоссылок и циклов.
  • Цепочка названий соответствует товару.
  • Формат ID и число элементов сверены с требованиями получателя.

Требования сверены с официальными справками Яндекса 8 сентября 2026 года. Ссылки на них приведены в разделе о различиях сервисов.

 Вернуться в блог

Оформление подписки недоступно

В данный момент оформить подписку нельзя. Попробуйте позже.