Парсинг зображень товарів для 1С-Бітрікс
Каталог без зображень не продає. Ми знаємо це не з чуток: на одному з проєктів для інтернет-магазину електроніки потрібно було завантажити 15 000 фото від 50 постачальників. Ручне завантаження зайняло б місяць. Ми написали парсер, який впорався за два дні. Нещодавно до нас звернувся інтернет-магазин запчастин з каталогом у 20 тис. позицій. Постачальник надавав зображення лише через API, але API віддавав посилання з обмеженням за часом. Ми розробили скрипт, який завантажував фото паралельно, обробляв помилки та прив'язував до інфоблоків. Результат — повний каталог із зображеннями за 3 дні. У цій статті розповімо, як автоматизувати завантаження зображень товарів у 1С-Бітрікс, які підводні камені трапляються і як їх обійти.
Як Бітрікс зберігає зображення товарів
Зображення зберігаються в таблиці b_file, фізично — в /upload/iblock/. Як зазначено в офіційній документації по зберіганню файлів, елемент інфоблоку зв'язується із зображенням через поля:
Зображення товарів зберігаються в таблиці b_file, а зв'язок з елементами інфоблоку здійснюється через поля PREVIEW_PICTURE та DETAIL_PICTURE.
-
PREVIEW_PICTURE — прев'ю для лістингу (ID запису в b_file)
-
DETAIL_PICTURE — основне фото для картки
- Властивість типу
F (файл) або G (галерея) — для додаткових зображень
Для галереї використовується властивість типу F з флагом MULTIPLE = Y. Стандартний компонент bitrix:catalog.element бере зображення з цієї властивості.
Завантаження та збереження: покрокова інструкція
Процес складається з трьох етапів: завантажити файл, зберегти через CFile, прив'язати до елемента.
// Крок 1: завантаження файлу (з таймаутом та повторними спробами)
$imageData = file_get_contents($imageUrl);
// Крок 2: збереження через CFile::MakeFileArray()
$tmpFile = tempnam(sys_get_temp_dir(), 'img_');
file_put_contents($tmpFile, $imageData);
$fileArray = CFile::MakeFileArray($tmpFile);
$fileArray['name'] = $filename;
$fileId = CFile::SaveFile($fileArray, 'iblock');
// Крок 3: прив'язка до властивості галереї
CIBlockElement::SetPropertyValuesEx($elementId, $iblockId, [
'MORE_PHOTO' => ['n0' => ['VALUE' => $fileId]]
]);
Для кількох зображень використовуємо індекси n0, n1, n2 і т.д. Важно: при великій кількості файлів використовуйте агенти або queue-обробку, щоб не перевищити ліміти виконання.
Проблеми при завантаженні зображень
Захист від хотлінкінгу. Багато сайтів-джерел перевіряють Referer. Передаємо коректний заголовок:
$client->get($url, ['headers' => ['Referer' => 'https://source-site.com']]);
Якість зображень. Не всі знайдені фото придатні для каталогу. Перевіряємо мінімальний розмір перед збереженням:
$imageInfo = getimagesizefromstring($imageData);
if ($imageInfo[0] < 300 || $imageInfo[1] < 300) continue; // пропускаємо дрібні
Дублікати. Один і той самий URL може зустрічатися на різних сторінках. Кешуємо вже завантажені URL → file_id в пам'яті або в окремій таблиці.
Витяг URL зображень із джерела
Для одного головного фото:
$src = $crawler->filter('.product-image img')->attr('src');
Для галереї — часто зображення в data-атрибутах або всередині JavaScript. Приклад з data-атрибутами:
$crawler->filter('[data-image]')->each(function($node) use (&$urls) {
$urls[] = $node->attr('data-image');
});
Якщо масив зображень лежить в JSON-LD, парсимо його стандартним json_decode.
Обробка вже існуючих зображень
Не затираємо фото, завантажені вручну або з 1С. Логіка:
- Перевіряємо
PREVIEW_PICTURE — якщо 0 або пустий, додаємо.
- Для галереї — додаємо тільки якщо властивість
MORE_PHOTO пуста.
- Помічаємо парсингові фото міткою в імені файлу (
parsed_ prefix) для подальшої ідентифікації.
Чому парсинг вигідніший за ручне завантаження?
Парсинг зображень у 10 разів швидший за ручне наповнення і обходиться в 3-5 разів дешевше. Це дозволяє суттєво економити бюджет на наповнення каталогу.
| Параметр |
Ручне завантаження |
Парсинг |
| Час на 10 000 фото |
20–30 робочих днів |
2–4 дні |
| Помилки вводу |
Висока ймовірність описок і невідповідностей |
Мінімальна (після налагодження скрипту) |
| Вартість |
Висока (оплата праці менеджерів) |
Низька (одноразова розробка) |
| Масштабованість |
Обмежена людськими ресурсами |
Легко масштабується на будь-який обсяг |
Парсинг окупається вже на каталозі від 500 товарів. Крім того, автоматизація виключає "людський фактор" — переплутані фото або неправильні прив'язки залишаються в минулому.
Як уникнути дублікатів при парсингу?
Дублікати виникають, коли один і той самий URL завантажується кілька разів. Рішення — вести облік уже оброблених URL. Найпростіший спосіб: зберігати масив url => file_id в пам'яті скрипту або в окремому HL-блоці. При повторній зустрічі URL одразу використовуємо збережений file_id.
Що входить в нашу роботу з парсингу зображень?
- Аналіз джерела — визначення структури сторінок, методів доступу (API, парсинг HTML), оцінка обсягу.
- Розробка парсера — скрипт на PHP, що враховує особливості джерела (AJAX, захист, капча).
- Обробка помилок — retry при тимчасових збоях, логування невдач, сповіщення про проблеми.
- Прив'язка до інфоблоків — створення нових елементів або оновлення існуючих, заповнення PREVIEW_PICTURE, DETAIL_PICTURE та властивостей галереї.
- Тестування — прогін на 100–500 товарах, перевірка якості зображень, відповідність розмірам.
- Документація — опис архітектури скрипту, інструкція з запуску та підтримки.
- Супровід — якщо джерело зміниться, ми адаптуємо парсер (договір на підтримку).
Орієнтовні терміни
| Етап |
Термін |
| Аналіз структури джерела |
2–4 години |
| Завантаження, валідація, збереження через CFile |
1–2 дні |
| Прив'язка до елементів інфоблоку (прев'ю + галерея) |
4–8 годин |
| Обробка помилок, retry, логування |
4 години |
| Тестовий прогін на 500 позиціях |
4 години |
| Разом |
3–5 робочих днів |
При каталозі від 10 000 зображень додається 1–2 дні на паралелізацію завантаження. Точні терміни залежать від складності джерела та вимог до якості.
Наш досвід та гарантії
Ми займаємося розробкою на 1С-Бітрікс більше 5 років і реалізували 30+ проєктів з наповнення каталогів. Наші інженери сертифіковані та знають усі тонкощі API. Гарантуємо, що після парсингу всі зображення будуть коректно прив'язані, а дублікати виключені. Зв'яжіться з нами для оцінки вашого проєкту — ми підготуємо пропозицію протягом дня. Отримайте консультацію з автоматизації каталогу.
З чого почати розробку парсера для 1С-Бітрікс?
XMLReader, а не SimpleXML — вибір інструмента визначає долю проекту. SimpleXML завантажує весь XML у пам’ять, і при файлі постачальника на 800 МБ PHP впаде з fatal error на ліміті 512 МБ. XMLReader обробляє потоково, node за node, споживаючи 20–30 МБ — в 30 разів ефективніше. З цієї деталі стартує будь-яка розробка парсерів під Бітрікс. Ми робимо такі системи вже понад 10 років, реалізували 50+ проектів, і жоден не обходиться без правильного вибору парсера.
Проблеми, які вирішує парсинг
- Первинне наповнення каталогу — 15 000 карток з описами, характеристиками, фото. Вручну це три місяці контент-менеджера; парсер — тиждень з налагодженням. Економія часу — до 90%.
- Моніторинг цін конкурентів — збір даних з Ozon, Wildberries, сайтів конкурентів. Конкурент знизив ціну на ходову позицію — дізнаєтеся через дві години, а не через два тижні. Окупається за 2–3 місяці.
- Агрегація постачальників — п’ять прайсів у різних форматах (CSV з CP1251, XML у CommerceML, Excel з об’єднаними комірками) перетворюються на єдиний каталог із загальною системою властивостей інфоблоку.
- Збагачення карток — підтягуємо характеристики, інструкції, 3D-моделі з сайтів виробників. Без цього картка товару — пустушка для SEO.
- Оновлення асортименту — товари, які зникли з фіду постачальника, деактивуються через
CIBlockElement::Update($ID, ['ACTIVE' => 'N']). Нові — створюються. Каталог синхронізовано.
Інструменти для розробки парсерів
Статичні сайти — PHP (Goutte, Symfony DomCrawler) або Python (Scrapy, lxml). Швидкість: 50–100 сторінок/сек. Вистачає для каталогів без JS-рендерингу.
SPA та динамічні сайти — Puppeteer або Playwright. Нескінченний скрол, AJAX-фільтри, lazy-load картинок — headless-браузер все це обробить. Швидкість падає до 1–10 сторінок/сек, але альтернативи немає: дані існують лише після виконання JavaScript.
Файли постачальників:
- Excel (XLS, XLSX) — PhpSpreadsheet. Обережно з об’єднаними комірками та формулами — вони ламають автоматичний мапінг.
- CSV —
fgetcsv() з правильною кодуванням. Постачальники люблять CP1251, BOM у UTF-8 та крапку з комою замість коми. Все це потрібно детектувати та обробляти.
- XML/YML — XMLReader для великих файлів, SimpleXML для фідів до 50 МБ.
- CommerceML — стандартний формат обміну з 1С. Розбираємо
import.xml та offers.xml, мапимо на структуру інфоблоків.
API — REST-ендпоінти постачальників, API маркетплейсів (Ozon Seller API, Wildberries API). Працюємо в рамках rate limits, обробляємо пагінацію.
Як влаштований пайплайн автонаповнення?
Чотири етапи. Кожен може зламатися по-своєму.
-
Збір. Парсер обходить джерела по cron-розкладу. Сирі дані пишемо в проміжну таблицю — не одразу в b_iblock_element. Логуємо все: скільки сторінок обійшли, скільки елементів розпарсили, де отримали 403 або timeout. Без логів налагодження парсера — ворожіння на кавовій гущі.
-
Нормалізація. Тут основна робота:
- Очищення HTML-тегів, зайвих пробілів, Unicode-сміття
- Одиниці виміру: «мм» → «мм», «millimeters» → «мм», «миллиметр» → «мм»
- Мапінг категорій постачальника → розділи інфоблоку Бітрікс. В одного постачальника «Ноутбуки», в іншого «Ноутбуки та планшети», у третього «Laptops» — все в одну секцію
- Дедуплікація за артикулом, EAN/GTIN. Один товар від трьох постачальників не повинен з’явитися тричі
-
Завантаження в Бітрікс. Через CIBlockElement::Add() для нових елементів, CIBlockElement::Update() для існуючих. Зображення: завантажуємо, ресайзимо через CFile::ResizeImageGet(), конвертуємо в WebP. Властивості — через CIBlockElement::SetPropertyValuesEx(). SEO-мета через \Bitrix\Iblock\InheritedProperty\ElementValues. ЧПУ генеруємо з транслітерації назви.
-
Оновлення. Ключовий момент — не затерти ручні правки контент-менеджера. Оновлюємо лише ціну, залишки, активність. Опис та фото, доопрацьовані вручну, позначаємо прапорцем UF_MANUAL_EDIT у властивостях елемента і пропускаємо при імпорті. Товари, що зникли з фіду — деактивуємо, але не видаляємо.
Моніторинг цін конкурентів: необхідність та реалізація
Окрема підсистема зі своєю специфікою:
| Параметр |
Як влаштовано |
| Частота |
Від разу на день до кожних 2 годин — залежить від волатильності ринку |
| Зіставлення |
За артикулом, EAN, нечітке порівняння назв через відстань Левенштейна |
| Зберігання |
Своя таблиця vendor_price_monitor з історією, не інфоблоки |
| Алерти |
Telegram/email при відхиленні ціни конкурента більш ніж на X% |
| Автоправила |
«Тримати ціну на 3% нижче мінімальної серед конкурентів, але не нижче собівартості + 15%» |
Результат — дашборд: ваш товар vs конкуренти, історія цін, тренди. Менеджер бачить, де можна підняти ціну без втрати позиції, а де потрібно реагувати.
Модуль імпорту CSV/XML: налаштування під ваш формат
Для файлів від постачальників — кастомний модуль з адмінкою:
- Налаштовуваний мапінг: «колонка B у файлі → властивість BRAND інфоблоку»
- Автодетект кодування (CP1251, UTF-8, UTF-16) через
mb_detect_encoding() з перевіркою
- Завантаження зображень за URL з чергою агентів Bitrix — щоб не забити канал
- Інкрементальне оновлення за хешем рядка: змінився рядок — оновлюємо, ні — пропускаємо
- Cron-розклад, звіт: створено 145, оновлено 892, помилок 3 (з деталями)
Великі файли: CSV обробляємо батчами по 1000 рядків через fgetcsv(), XML потоково через XMLReader, фонове виконання через чергу агентів Бітрікс — ніяких PHP-таймаутів.
Правова сторона — що важливо врахувати
-
robots.txt — поважаємо. Crawl-delay — дотримуємося.
- Частота запитів — 1–2 в секунду, не більше. Не потрібно DDoS-ити чужий сайт.
- Контент виробників — використовуємо. Унікальні авторські тексти — не копіюємо.
- Персональні дані — не збираємо.
Що входить в розробку парсера під ключ?
| Складова |
Опис |
| Прототип |
Парсер 1–2 джерел за 2–3 дні для оцінки якості даних |
| Основний парсер |
Повний збір даних з одного джерела (статичний/динамічний) |
| Модуль імпорту в Бітрікс |
Нормалізація, завантаження, оновлення, адмінка мапінгу |
| Моніторинг цін |
Якщо потрібно – система збору та алертів (до 10 конкурентів) |
| Документація |
Опис архітектури, інструкція з оновлення селекторів |
| Підтримка |
Гарантія 3 місяці на безперебійну роботу, правка при зміні верстки донора |
Скільки часу займає розробка парсера?
Процес і терміни:
-
Прототип — парсер для 1–2 джерел за 2–3 дні. Оцінюємо якість даних, підводні камені (захист Cloudflare, капча, динамічне підвантаження).
-
Розробка — повний пайплайн: парсер → нормалізація → імпорт в Бітрікс → адмінка для управління.
-
Тестування — проганяємо на повному обсязі каталогу, перевіряємо edge-кейси (порожні поля, кривий HTML, биті картинки).
-
Запуск — налаштовуємо cron, моніторинг помилок через Telegram-бот.
-
Підтримка — конкурент переробив верстку? Оновлюємо CSS-селектори в парсері.
Орієнтовні терміни для різних типів завдань
| Задача |
Терміни |
| Парсер одного сайту (статичний HTML) |
3–5 днів |
| Парсер SPA-сайту (Puppeteer/Playwright, обхід захисту) |
1–2 тижні |
| Модуль імпорту CSV/XML в Бітрікс |
1–2 тижні |
| Система моніторингу цін (5–10 конкурентів) |
2–4 тижні |
| Комплексна система автонаповнення |
4–8 тижнів |
| Підтримка та адаптація парсерів |
за підпискою |
Отримайте консультацію: розкажіть про своє джерело даних — ми підберемо оптимальний підхід. Зв’яжіться для оцінки вашого проекту — запропонуємо рішення під ваш бюджет. Гарантуємо стабільну роботу парсерів і повну підтримку.