Реализация импорта товаров из прайс-агрегаторов

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

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

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

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

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Реализация импорта товаров из прайс-агрегаторов
Средняя
~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

Реализация импорта товаров из прайс-агрегаторов

Прайс-агрегаторы — Яндекс.Маркет, Price.ru, Pricelist.ru, E-Katalog и другие — аккумулируют данные о товарах от множества магазинов и производителей. Для интернет-магазина они могут быть источником обогащения каталога: описания, характеристики, изображения и ценовые ориентиры по рынку. Особенность работы с агрегаторами — у каждого свой формат выгрузки и своя модель доступа.

Источники данных агрегаторов

Агрегатор Формат данных Способ получения
Яндекс.Маркет YML (экспорт прайса) Выгрузка из личного кабинета
Price.ru XML / CSV FTP или HTTP
E-Katalog XML с характеристиками API (платный) или выгрузка
OZON JSON через API Seller REST API
Wildberries JSON через API Supplier REST API
Pricelist.ru CSV HTTP

Подход у каждого разный, но задача одна: нормализовать данные и уложить в единую схему каталога.

Адаптерный слой

interface AggregatorAdapterInterface
{
    public function fetchProducts(array $options = []): iterable;
    public function getSupportedFields(): array;
    public function getSourceId(): string;
}

Регистрация в сервис-контейнере:

$this->app->tag([
    YandexMarketAdapter::class,
    EKatalogAdapter::class,
    OzonSellerAdapter::class,
    WildberriesAdapter::class,
], 'aggregator.adapters');

E-Katalog: характеристики и сравнения

E-Katalog — наиболее богатый источник технических характеристик. Их XML содержит стандартизованные спецификации с единицами измерения:

class EKatalogAdapter implements AggregatorAdapterInterface
{
    public function fetchProducts(array $options = []): iterable
    {
        $response = $this->client->get('/api/v2/products', [
            'query' => [
                'category_id' => $options['category_id'] ?? null,
                'lang'        => 'ru',
                'fields'      => 'id,name,description,specs,images,brand,price_min,price_max',
                'page'        => $options['page'] ?? 1,
                'per_page'    => 200,
            ],
            'headers' => ['Authorization' => 'Bearer ' . $this->apiKey],
        ]);

        foreach ($response->json('products') as $product) {
            yield $this->normalize($product);
        }
    }

    private function normalize(array $raw): array
    {
        $specs = [];
        foreach ($raw['specs'] ?? [] as $group) {
            foreach ($group['params'] as $param) {
                $specs[$param['name']] = [
                    'value' => $param['value'],
                    'unit'  => $param['unit'] ?? null,
                ];
            }
        }

        return [
            'external_id'  => 'ekatalog_' . $raw['id'],
            'name'         => $raw['name'],
            'description'  => $raw['description'],
            'brand'        => $raw['brand']['name'] ?? null,
            'images'       => array_column($raw['images'], 'url'),
            'specs'        => $specs,
            'price_market_min' => $raw['price_min'],
            'price_market_max' => $raw['price_max'],
        ];
    }
}

OZON Seller API: актуальные данные по товарам

Если магазин торгует на OZON, можно тянуть оттуда контент:

class OzonSellerAdapter implements AggregatorAdapterInterface
{
    public function fetchProducts(array $options = []): iterable
    {
        // OZON API v3: получение списка товаров продавца
        $response = Http::withToken($this->apiKey)
            ->withHeaders(['Client-Id' => $this->clientId])
            ->post('https://api-seller.ozon.ru/v3/product/list', [
                'filter' => ['visibility' => 'ALL'],
                'limit'  => 1000,
                'last_id' => $options['last_id'] ?? '',
            ]);

        $items = $response->json('result.items');

        // Получаем детали батчами по 100
        foreach (array_chunk(array_column($items, 'product_id'), 100) as $batch) {
            $details = Http::withToken($this->apiKey)
                ->withHeaders(['Client-Id' => $this->clientId])
                ->post('https://api-seller.ozon.ru/v2/product/info/list', [
                    'product_id' => $batch,
                ])->json('result.items');

            foreach ($details as $detail) {
                yield $this->normalizeOzon($detail);
            }
        }
    }
}

Использование рыночных цен для аналитики

Агрегаторы дают возможность отслеживать конкурентное ценообразование:

CREATE TABLE market_price_data (
    product_id      int REFERENCES products(id),
    source          varchar(50),      -- 'ekatalog' | 'yandex_market' | 'price_ru'
    price_min       numeric(12,2),
    price_max       numeric(12,2),
    price_avg       numeric(12,2),
    offers_count    int,
    collected_at    timestamptz DEFAULT now()
);

На основе этих данных можно автоматически устанавливать цену как «рыночный минимум - 5%» или «выше среднего на 2%» — динамическое ценообразование на основе реальных данных.

Обогащение существующих товаров

Основной кейс: в каталоге есть товар с артикулом, но без характеристик и описания. Агрегатор знает этот товар по GTIN или названию бренда+модели:

class ProductEnrichmentService
{
    public function enrich(Product $product): bool
    {
        // Поиск по GTIN у агрегаторов
        foreach ($this->adapters as $adapter) {
            $data = $adapter->findByGtin($product->gtin);
            if (!$data) $data = $adapter->findByBrandModel($product->brand, $product->model);
            if (!$data) continue;

            $this->applyEnrichment($product, $data, $adapter->getSourceId());
            return true;
        }
        return false;
    }

    private function applyEnrichment(Product $product, array $data, string $source): void
    {
        // Обогащаем только пустые поля — не перезаписываем существующее
        if (!$product->description && !empty($data['description'])) {
            $product->description        = $data['description'];
            $product->description_source = $source;
        }

        if (empty($product->specs) && !empty($data['specs'])) {
            foreach ($data['specs'] as $name => $spec) {
                ProductSpec::updateOrCreate(
                    ['product_id' => $product->id, 'name' => $name],
                    ['value' => $spec['value'], 'unit' => $spec['unit'], 'source' => $source]
                );
            }
        }

        $product->save();
    }
}

Дедупликация при мультиагрегаторном обогащении

Когда несколько агрегаторов предоставляют данные для одного товара — нужна стратегия приоритетов:

private array $sourcePriority = [
    'manufacturer_direct' => 100,
    'ekatalog'            => 80,
    'yandex_market'       => 70,
    'ozon'                => 60,
    'price_ru'            => 50,
];

Более приоритетный источник перезаписывает менее приоритетный. Приоритет хранится в product_specs.source_priority.

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

  • Один адаптер (YML от Яндекс.Маркет), обогащение пустых полей — 2 дня
  • Мультиагрегаторная структура + приоритеты + рыночные цены — +2 дня
  • OZON/WB API, динамическое ценообразование на основе рынка — +2–3 дня