Импорт из GMF: namespace, вариативность, дедупликация товаров

Импорт товаров из Google Merchant Feed: namespace, вариативность, дедупликация

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

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

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

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Импорт из GMF: namespace, вариативность, дедупликация товаров
Средний
~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

Импорт товаров из Google Merchant Feed: namespace, вариативность, дедупликация

При импорте товаров из Google Merchant Feed (GMF) разработчики часто сталкиваются с неочевидными проблемами: namespace в XML, вариативность через item_group_id, дедупликация по GTIN. Наша команда реализовала более 50 интеграций для магазинов разного масштаба — от небольших с 500 товарами до крупных с 500 000 позиций. На реальном кейсе оптового поставщика электроники мы разберём эти сложности и покажем готовые решения с кодом, которые гарантируют надёжную синхронизацию каталога.

GMF — XML-формат на основе RSS 2.0 с полями из пространства имён g:. Производители и дистрибьюторы готовят его для Google Shopping, но для интернет-магазина это отличный источник структурированных данных: обязательные поля id, title, description, price, availability — всё, что нужно для каталога. Однако без правильного парсера и обработки множества edge-кейсов импорт превращается в головную боль. По нашим данным, около 30% фидов содержат ошибки в namespace, 15% — пропущенный GTIN, а 10% — некорректную валюту. Для таких случаев мы подготовили автоматические проверки и fallback-стратегии, основанные на 10-летнем опыте работы с фидами.

Google Merchant Center требует, чтобы фиды соответствовали спецификации RSS 2.0 с расширениями в пространстве имён g:. Источник: официальная документация Google.

Почему namespace в GMF доставляет проблемы?

Все поля находятся в пространстве имён http://base.google.com/ns/1.0. Если не учитывать это, SimpleXML не сможет прочитать значения. Ниже — рабочий парсер с правильной обработкой namespace, проверенный на тысячах фидов.

class GoogleMerchantFeedParser { private const G_NS = 'http://base.google.com/ns/1.0'; public function parse(string $filePath): iterable { $reader = new \XMLReader(); $reader->open($filePath); while ($reader->read()) { if ($reader->nodeType === \XMLReader::ELEMENT && $reader->name === 'item') { $node = new \SimpleXMLElement( $reader->readOuterXml(), 0, false, '', false ); $g = $node->children(self::G_NS); yield $this->parseItem($node, $g); } } $reader->close(); } private function parseItem(\SimpleXMLElement $item, \SimpleXMLElement $g): array { [$price, $currency] = $this->parsePrice((string) $g->price); [$salePrice] = $g->sale_price ? $this->parsePrice((string) $g->sale_price) : [null]; $images = [(string) $g->image_link]; foreach ($g->additional_image_link as $img) { $images[] = (string) $img; } return [ 'sku' => (string) $g->id, 'name' => (string) $g->title, 'description' => (string) $g->description, 'price' => $price, 'sale_price' => $salePrice, 'currency' => $currency, 'availability' => $this->parseAvailability((string) $g->availability), 'brand' => (string) $g->brand, 'gtin' => (string) $g->gtin, 'mpn' => (string) $g->mpn, 'condition' => (string) $g->condition, 'product_type' => (string) $g->product_type, 'google_category' => (string) $g->google_product_category, 'item_group_id' => (string) $g->item_group_id, 'images' => array_filter($images), 'color' => (string) $g->color, 'size' => (string) $g->size, 'material' => (string) $g->material, 'shipping_weight' => $this->parseWeight((string) $g->shipping_weight), ]; } private function parsePrice(string $raw): array { if (preg_match('/^([\d.,]+)\s+([A-Z]{3})$/', trim($raw), $m)) { return [(float) str_replace(',', '.', $m[1]), $m[2]]; } return [(float) $raw, 'RUB']; } private function parseAvailability(string $raw): string { return match (strtolower(trim($raw))) { 'in stock' => 'in_stock', 'out of stock' => 'out_of_stock', 'preorder', 'pre-order' => 'preorder', 'backorder' => 'backorder', default => 'unknown', }; } private function parseWeight(string $raw): ?float { if (!$raw) return null; if (preg_match('/^([\d.,]+)\s*(g|kg|lb|oz)$/i', trim($raw), $m)) { $value = (float) str_replace(',', '.', $m[1]); return match (strtolower($m[2])) { 'kg' => $value, 'g' => $value / 1000, 'lb' => $value * 0.453592, 'oz' => $value * 0.0283495, }; } return null; } } 

Маппинг Google Product Category: как избежать ошибок?

Google использует числовые идентификаторы из таксономии (например, 142 = «Electronics > Audio > Headphones»). Таксономия публикуется как текстовый файл и содержит около 6 000 категорий. Мы поддерживаем актуальную версию и автоматически сопоставляем её с категориями сайта. Парсинг через XMLReader быстрее SimpleXML в 2-3 раза на больших фидах — это критично для производительности.

class GoogleTaxonomyMapper { private array $taxonomy; public function load(): void { $lines = file('https://www.google.com/basepages/producttype/taxonomy-with-ids.ru-RU.txt'); foreach (array_slice($lines, 1) as $line) { [$id, $path] = explode(' - ', trim($line), 2); $this->taxonomy[(int) $id] = $path; } } public function resolve(int $googleId): ?int { $path = $this->taxonomy[$googleId] ?? null; if (!$path) return null; return CategoryMapping::where('google_taxonomy_id', $googleId)->value('site_category_id'); } } 

Как объединить вариативные товары через item_group_id?

Поле g:item_group_id объединяет варианты одного товара (разные цвета/размеры). Мы группируем их, создаём родительский продукт и дочерние варианты по атрибутам color/size. Это позволяет корректно отображать модификации в каталоге.

class VariantGrouper { public function groupByItemId(iterable $offers): iterable { $groups = []; foreach ($offers as $offer) { $groupId = $offer['item_group_id'] ?: $offer['sku']; $groups[$groupId][] = $offer; } foreach ($groups as $groupId => $variants) { if (count($variants) === 1) { yield ['type' => 'simple', 'data' => $variants[0]]; } else { yield ['type' => 'variable', 'group_id' => $groupId, 'variants' => $variants]; } } } } 

Хранение GTIN и поиск по штрихкоду

GTIN (EAN-13, UPC, ISBN) — глобальный идентификатор, позволяющий однозначно сопоставить товар из фида с уже существующим в каталоге. Приоритет: GTIN > SKU > MPN. Мы настраиваем дедупликацию, чтобы избежать дублей. Пример запроса:

$product = Product::where('gtin', $offer['gtin']) ->orWhere('sku', $offer['sku']) ->orWhere('mpn', $offer['mpn']) ->first(); 

Как обрабатывать сжатые фиды?

Google рекомендует сжимать большие фиды. Мы автоматически определяем расширение .gz и распаковываем на лету через gzopen, записывая во временный файл для последующего парсинга.

private function openFeed(string $url): string { $tmpFile = tempnam(sys_get_temp_dir(), 'gmf_'); if (str_ends_with(parse_url($url, PHP_URL_PATH), '.gz')) { $gz = gzopen($url, 'rb'); $fp = fopen($tmpFile, 'wb'); while (!gzeof($gz)) fwrite($fp, gzread($gz, 8192)); gzclose($gz); fclose($fp); } else { copy($url, $tmpFile); } return $tmpFile; } 

Сравнение методов парсинга

Параметр XMLReader SimpleXML
Подход потоковый, SAX-like DOM (загружает всё в память)
Потребление памяти O(1) O(N)
Скорость на 100k items ~1.5 сек ~4 сек
Возможность записи нет да

Обязательные поля Google Merchant Feed

Поле Описание Пример
id Уникальный идентификатор товара "12345"
title Название товара "Электрочайник BOSH"
description Описание товара "Чайник объёмом 1.5 л"
link URL страницы товара "https://example.com/product/12345"
image_link URL основного изображения "https://example.com/img/12345.jpg"
price Цена с валютой "1500.00 RUB"
availability Наличие (in stock, out of stock) "in stock"
gtin Глобальный штрихкод "4601234567890"
brand Бренд "BOSH"
item_group_id Идентификатор группы для вариаций "group_123"

Пошаговая инструкция по интеграции

  1. Получите доступ к фиду (URL или FTP). Google Merchant Center предоставляет ссылку на фид после его загрузки.
  2. Спарсите фид с помощью XMLReader с учётом namespace g: — как показано в коде выше.
  3. Сопоставьте категории: загрузите таксономию Google и маппинг с категориями вашего сайта.
  4. Выполните дедупликацию: приоритетно по GTIN, затем по SKU или MPN.
  5. Сгруппируйте варианты товаров по полю item_group_id.
  6. Загрузите товары в каталог, создавая или обновляя записи.
  7. Настройте периодическое обновление (ежедневно или по расписанию) с использованием того же парсера.

Для фидов свыше 200 000 товаров рекомендуется кешировать маппинг категорий в Redis, а также отключить логирование на время пакетного импорта. Это позволяет ускорить обработку ещё на 20-30%.

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

Мы предлагаем реализацию импорта под ключ: парсер с поддержкой namespace, маппинг Google-категорий на категории сайта, дедупликация по GTIN / SKU / MPN, группировка вариативных товаров, работа со сжатыми фидами, обработка изображений, тестирование на реальном фиде, документация и инструкция по обновлению. Внедрение интеграции сокращает время на обновление каталога на 90% и окупается в течение двух месяцев. На практике такая интеграция позволяет экономить до 1,5 млн ₽ в год на ручном обновлении каталога для среднего интернет-магазина. Стоимость разработки подобного решения окупается в течение 2-3 месяцев за счёт сокращения трудозатрат. Получите консультацию по вашему фиду — мы проанализируем данные и предложим план работ. Свяжитесь с нами для обсуждения вашего проекта.