Реализация автоматического обновления описаний и характеристик товаров

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

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

Информационные сайты или веб-приложения
Сайты визитки, 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

Реализация автоматического обновления описаний и характеристик товаров

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

Структура данных для управляемого обновления

Ключевой принцип: разделять источник данных (поставщик) и финальный контент (что показывается на сайте), с флагом «вручную отредактировано».

CREATE TABLE product_content (
    product_id          int        REFERENCES products(id),
    source              varchar(30),          -- supplier_id или 'manual'
    field               varchar(50),          -- description | spec_weight | spec_color ...
    value               text,
    is_manual_override  boolean DEFAULT false,
    supplier_value      text,                 -- последнее значение от поставщика
    updated_at          timestamptz,
    PRIMARY KEY (product_id, field)
);

При автообновлении: если is_manual_override = true — обновлять только supplier_value, но не value. Контент-менеджер видит расхождение в интерфейсе и решает, принять ли изменение поставщика.

Источники описаний

XML-фид поставщика

Большинство производственных компаний предоставляют XML с расширенными атрибутами:

<product article="ABC-123">
  <description lang="ru"><![CDATA[Подробное описание...]]></description>
  <attributes>
    <attribute name="weight" unit="kg">2.5</attribute>
    <attribute name="color">Чёрный</attribute>
    <attribute name="material">Нержавеющая сталь</attribute>
  </attributes>
</product>

Парсер на PHP:

class XmlDescriptionSource implements DescriptionSourceInterface
{
    public function fetch(): iterable
    {
        $xml = new \XMLReader();
        $xml->open($this->url);

        while ($xml->read()) {
            if ($xml->nodeType === \XMLReader::ELEMENT && $xml->name === 'product') {
                $node = new \SimpleXMLElement($xml->readOuterXml());
                yield $this->parseProduct($node);
            }
        }
        $xml->close();
    }

    private function parseProduct(\SimpleXMLElement $node): array
    {
        $data = [
            'sku'         => (string) $node['article'],
            'description' => (string) $node->description,
            'attributes'  => [],
        ];
        foreach ($node->attributes->attribute as $attr) {
            $data['attributes'][(string) $attr['name']] = (string) $attr;
        }
        return $data;
    }
}

XMLReader читает файл потоково — не загружает весь XML в память, что критично при каталогах от 100 000 позиций.

API с частичным обновлением

Если поставщик предоставляет endpoint изменений:

GET /products/updates?fields=description,attributes&since=2024-01-15T10:00:00Z

Возвращает только товары, у которых изменилось хотя бы одно из указанных полей — существенно сокращает объём обработки.

Обновление характеристик с нормализацией

Поставщик присылает характеристики в собственном формате — нужно привести к внутренней схеме сайта:

class AttributeNormalizer
{
    // Маппинг имён атрибутов поставщика → внутренние ключи
    private array $nameMap = [
        'weight'       => 'spec_weight_kg',
        'масса'        => 'spec_weight_kg',
        'вес нетто'    => 'spec_weight_kg',
        'color'        => 'spec_color',
        'цвет'         => 'spec_color',
    ];

    public function normalize(string $supplierName, mixed $value): ?array
    {
        $key = $this->nameMap[mb_strtolower(trim($supplierName))] ?? null;
        if (!$key) return null;

        return ['key' => $key, 'value' => $this->castValue($key, $value)];
    }

    private function castValue(string $key, mixed $raw): mixed
    {
        return match(true) {
            str_starts_with($key, 'spec_weight') => (float) str_replace(',', '.', $raw),
            default => (string) $raw,
        };
    }
}

Job-цепочка для обновления контента

Обновление описаний тяжелее обновления цен — контент большой, нужно нормализовать атрибуты, сравнивать с override-флагами. Оптимальная схема: отдельная очередь с низким параллелизмом.

class UpdateProductDescriptionsJob implements ShouldQueue
{
    public int $tries = 3;
    public int $backoff = 60; // секунды между повторами

    public function handle(
        DescriptionSourceInterface $source,
        AttributeNormalizer        $normalizer,
        ContentUpdater             $updater,
    ): void {
        foreach ($source->fetch() as $item) {
            $productId = Product::where('sku', $item['sku'])->value('id');
            if (!$productId) continue;

            // Описание
            $updater->updateField($productId, 'description', $item['description']);

            // Характеристики
            foreach ($item['attributes'] as $name => $value) {
                $normalized = $normalizer->normalize($name, $value);
                if ($normalized) {
                    $updater->updateField($productId, $normalized['key'], $normalized['value']);
                }
            }
        }
    }
}

Логика ContentUpdater

class ContentUpdater
{
    public function updateField(int $productId, string $field, mixed $newValue): void
    {
        $existing = ProductContent::where([
            'product_id' => $productId,
            'field'      => $field,
        ])->first();

        if (!$existing) {
            ProductContent::create([
                'product_id'     => $productId,
                'field'          => $field,
                'value'          => $newValue,
                'supplier_value' => $newValue,
            ]);
            return;
        }

        // Всегда обновляем supplier_value для отображения расхождения
        $existing->supplier_value = $newValue;

        // Перезаписываем только если нет ручного оверрайда
        if (!$existing->is_manual_override) {
            $existing->value = $newValue;
        }

        $existing->updated_at = now();
        $existing->save();
    }
}

Расписание и приоритеты

Тип данных Частота Причина
Характеристики (размеры, вес) Раз в сутки Меняются редко
Описания Раз в сутки Большой объём, не срочно
Статусы сертификатов Раз в неделю Изменяются ещё реже
Цены Каждые 15–30 мин Высокая волатильность

Интерфейс расхождений в админке

Если value != supplier_value AND is_manual_override = true, показывать в интерфейсе товара предупреждение: «Поставщик изменил значение. Текущее: X, новое от поставщика: Y. Принять?» с кнопками «Принять» и «Оставить».

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

  • Один XML-источник, обновление описания и атрибутов без оверрайдов — 2–3 дня
  • Нормализатор атрибутов с маппинг-таблицей + оверрайд-механизм — +2 дня
  • Дашборд расхождений в админке — +1–2 дня