Після 200–300 запитів з однієї IP-адреси джерело починає віддавати 429 Too Many Requests або капчу. Це стандартний захист: Cloudflare, DataDome, PerimeterX — всі відстежують частоту запитів за IP. Єдиний спосіб обійти rate-limiting при промисловому парсингу — ротація проксі. Розберемо інтеграцію пулу проксі в парсер на Бітрікс. Ми налаштовуємо таку систему під ключ: від підбору пулу до health-check агента. Згідно з даними Cloudflare, близько 30% всього інтернет-трафіку генерується ботами, і захист від них стає тільки жорсткішим.
Типи проксі і що вибрати
| Тип проксі |
Вартість |
Швидкість |
Виявлюваність |
Рекомендація |
| Датацентрові |
$1–3/IP |
Висока |
Легко за ASN |
Джерела без серйозного захисту |
| Резидентні |
$5–15/GB трафіку |
Середня |
Практично немає |
Cloudflare Enterprise, антиботи |
| Мобільні |
$10–30/GB |
Низька |
Не виявляються |
Агресивний захист, рідко для каталогів |
Датацентрові проксі в 10 разів дешевші за резидентні, але в 2 рази частіше блокуються. Для більшості задач автонаповнення каталогу в Бітрікс достатньо пулу з 20–50 датацентрових проксі. Резидентні — якщо джерело активно блокує.
Як працює проксі-ротація?
Ротація — це зміна IP перед кожним запитом або після N запитів. Парсер в Бітрікс зазвичай використовує \Bitrix\Main\Web\HttpClient або cURL напряму. Проксі задається через опції з'єднання. Задача — перед кожним запитом вибирати наступний проксі з пулу. Ми реалізуємо клас ProxyRotator з підтримкою cooldown для забанених проксі.
Зберігання пулу — таблиця або конфігураційний файл:
// /local/php_interface/parser/proxy_pool.php
return [
['host' => '185.1.2.3', 'port' => 8080, 'user' => 'u1', 'pass' => 'p1', 'type' => 'http'],
['host' => '185.1.2.4', 'port' => 8080, 'user' => 'u2', 'pass' => 'p2', 'type' => 'socks5'],
// ...
];
Клас ротатора:
class ProxyRotator
{
private array $pool;
private array $failed = [];
private int $index = 0;
public function next(): ?array
{
$attempts = count($this->pool);
while ($attempts-- > 0) {
$proxy = $this->pool[$this->index % count($this->pool)];
$this->index++;
$key = $proxy['host'] . ':' . $proxy['port'];
if (!isset($this->failed[$key]) || $this->failed[$key] < time()) {
return $proxy;
}
}
return null; // всі проксі в cooldown
}
public function markFailed(array $proxy, int $cooldownSec = 300): void
{
$key = $proxy['host'] . ':' . $proxy['port'];
$this->failed[$key] = time() + $cooldownSec;
}
}
Стратегії ротації:
- Round-robin — найпростіша, проксі використовуються по черзі. Працює при однорідному пулі.
- Random — випадковий вибір. Знижує передбачуваність патерну для anti-bot систем.
- Sticky per source — один проксі закріплюється за одним доменом-джерелом на N хвилин. Імітує реального користувача, знижує ймовірність блокування.
Для парсингу каталогів рекомендую sticky per source з ротацією кожні 50–100 запитів або при отриманні 429/403.
Чому sticky per source кращий за round-robin?
Sticky per source імітує поведінку реального користувача: один IP на один сайт. Це знижує частоту блокувань у 3–4 рази порівняно з round-robin. Однак якщо джерело має кілька доменів, sticky per source вимагає окремого проксі на кожен домен.
Інтеграція з HttpClient Бітрікс
$proxy = $rotator->next();
$http = new \Bitrix\Main\Web\HttpClient();
$http->setProxy($proxy['host'], $proxy['port'], $proxy['user'], $proxy['pass']);
$http->setTimeout(15);
$http->setStreamTimeout(30);
$response = $http->get($url);
if ($http->getStatus() === 429 || $http->getStatus() === 403) {
$rotator->markFailed($proxy, 600);
// retry з іншим проксі
}
При використанні cURL напряму — опції CURLOPT_PROXY, CURLOPT_PROXYUSERPWD, CURLOPT_PROXYTYPE (CURLPROXY_HTTP або CURLPROXY_SOCKS5).
Моніторинг здоров'я пулу
Проксі вмирають — закінчується термін, IP потрапляє в бан, провайдер відключає. Потрібен регулярний health-check. Агент, що запускається раз на годину, проходить по пулу і перевіряє кожен проксі запитом до https://httpbin.org/ip. Результат — оновлення статусу в конфігурації (active/dead). Мертві проксі автоматично виключаються з ротації.
Логуйте статистику по кожному проксі: кількість успішних запитів, кількість 429/403, середній час відповіді. Це дозволяє виявити «повільні» проксі і виключити їх до повної смерті.
Що робити при блокуванні проксі?
Якщо проксі отримує 429 або 403, наш ProxyRotator переводить його в cooldown на 5–10 хвилин. Але цього недостатньо. Додатково варто реалізувати експоненційну затримку: після кожної помилки збільшувати час очікування для даного IP. Також корисно вести чорний список проксі, які отримали постійний бан — їх потрібно виводити з пулу і замінювати свіжими.
Додаткові заходи
- Затримка між запитами — 1–5 секунд випадкової паузи. Навіть з ротацією проксі, кулеметна частота запитів виглядає підозріло.
- Ротація User-Agent — пул з 10–20 актуальних рядків UA, перемикається разом з проксі.
- Referer і заголовки — відправляйте
Accept-Language, Accept-Encoding, Referer від попередньої сторінки. Без них запит виглядає як бот.
Що входить в налаштування
- Підбір і закупівля пулу проксі (датацентрові або резидентні).
- Написання конфігураційного файлу або таблиці для зберігання списку проксі.
- Реалізація класу
ProxyRotator з обраною стратегією ротації.
- Інтеграція з
HttpClient або cURL в парсері.
- Написання health-check агента і логування статистики.
- Документація процесу для вашої команди.
З нашим досвідом (5+ років в Бітрікс-розробці, 50+ проектів з парсингу) ми гарантуємо стабільну роботу парсера навіть при агресивних антиботах. Зв'яжіться з нами для попередньої оцінки вашого завдання. Замовте налаштування парсингу під ключ — ми підготуємо рішення індивідуально.
З чого почати розробку парсера для 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 тижнів |
| Підтримка та адаптація парсерів |
за підпискою |
Отримайте консультацію: розкажіть про своє джерело даних — ми підберемо оптимальний підхід. Зв’яжіться для оцінки вашого проекту — запропонуємо рішення під ваш бюджет. Гарантуємо стабільну роботу парсерів і повну підтримку.