Розробка бота-парсера прайс-листів постачальників (Excel/CSV/XML)

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

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

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Розробка бота-парсера прайс-листів постачальників (Excel/CSV/XML)
Середня
~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

Парсер прайс-листів поставщиків (Excel/CSV/XML)

Поставщики присилають прайс-листи в різних форматах: Excel з нестандартною структурою, CSV з кирилицею в різних кодуваннях, XML різної степені стандартизованості. Завдання парсера — нормалізувати все це в єдиний формат та синхронізувати з каталогом магазину.

Типічні проблеми вхідних файлів

  • Excel: дані починаються з 3-го рядка, заголовки в об'єднаних ячейках
  • CSV: кодування windows-1251, розділювач — крапка з комою, ціни з пробілами
  • XML: нестандартні теги, простори імен, атрибути замість значень
  • Несогласовані формати SKU у різних поставщиків
  • Числа як рядки, дати як числа Excel

Парсер Excel (PhpSpreadsheet)

// app/Services/PriceList/ExcelParser.php
class ExcelParser {
    public function parse(string $filePath, array $config): array {
        $spreadsheet = IOFactory::load($filePath);
        $sheet = $spreadsheet->getActiveSheet();

        $this->detectColumns($sheet, $config['header_row'] ?? 1, $config['column_aliases']);

        $products = [];
        for ($row = $config['data_start_row'] ?? 2; $row <= $sheet->getHighestRow(); $row++) {
            $sku = $this->getCellValue($sheet, $this->columnMap['sku'], $row);
            if (empty($sku)) continue;

            $products[] = [
                'sku'   => trim($sku),
                'name'  => $this->getCellValue($sheet, $this->columnMap['name'] ?? null, $row),
                'price' => $this->parsePrice($this->getCellValue($sheet, $this->columnMap['price'], $row)),
                'stock' => $this->parseStock($this->getCellValue($sheet, $this->columnMap['stock'] ?? null, $row)),
            ];
        }

        return $products;
    }
}

CSV парсер з автовизначенням кодування

// app/Services/PriceList/CsvParser.php
class CsvParser {
    public function parse(string $filePath, array $config = []): array {
        $content = file_get_contents($filePath);

        // Автовизначення кодування
        $encoding = mb_detect_encoding($content, ['UTF-8', 'Windows-1251', 'KOI8-R'], true);
        if ($encoding && $encoding !== 'UTF-8') {
            $content = mb_convert_encoding($content, 'UTF-8', $encoding);
        }

        // Автовизначення розділювача
        $delimiter = $config['delimiter'] ?? $this->detectDelimiter($content);

        $lines = str_getcsv($content, "\n");
        $headers = str_getcsv(array_shift($lines), $delimiter);

        $products = [];
        foreach ($lines as $line) {
            if (empty(trim($line))) continue;
            $row = str_getcsv($line, $delimiter);
            $data = array_combine($headers, $row);
            $products[] = $this->normalizeRow($data, $config);
        }

        return $products;
    }
}

XML парсер

// app/Services/PriceList/XmlParser.php
class XmlParser {
    public function parse(string $filePath, array $config): array {
        $xml = simplexml_load_file($filePath, 'SimpleXMLElement', LIBXML_NOCDATA);

        $itemXpath = $config['item_xpath'] ?? '//item';
        $items = $xml->xpath($itemXpath);

        return array_map(fn($item) => $this->extractItem($item, $config), $items);
    }

    private function extractItem(\SimpleXMLElement $item, array $config): array {
        $fields = $config['fields'] ?? [];

        return [
            'sku'   => (string) $item->xpath($fields['sku'] ?? 'article')[0] ?? '',
            'name'  => (string) $item->xpath($fields['name'] ?? 'name')[0] ?? '',
            'price' => (float) ($item->xpath($fields['price'] ?? 'price')[0] ?? 0),
            'stock' => ((string) ($item->xpath($fields['stock'] ?? 'available')[0] ?? '1')) !== '0',
        ];
    }
}

Автоматичне отримання файлів

Прайс-листи надходять по email, FTP або HTTP:

// app/Jobs/FetchSupplierPriceList.php
class FetchSupplierPriceList implements ShouldQueue {
    public function handle(PriceListFetcher $fetcher, PriceListParser $parser): void {
        $supplier = Supplier::findOrFail($this->supplierId);

        $filePath = match ($supplier->price_list_source) {
            'ftp'   => $fetcher->downloadFromFtp($supplier),
            'url'   => $fetcher->downloadFromUrl($supplier->price_list_url),
            'email' => $fetcher->fetchFromEmail($supplier),
        };

        $config = config("price_list_parsers.{$supplier->config_key}");
        $products = $parser->parse($filePath, $config);

        foreach (array_chunk($products, 500) as $chunk) {
            ImportPriceListChunk::dispatch($supplier->id, $chunk);
        }
    }
}

Терміни розробки

Парсер для 1 поставщика (1 формат, стандартна структура): 2-4 робочих дні. Універсальний диспетчер + 5 поставщиків з різними форматами: 7-10 робочих днів.