Налаштування захисту контенту від парсингу 1С-Бітрікс

Наша компанія займається розробкою, підтримкою та обслуговуванням рішень на Бітрікс та Бітрікс24 будь-якої складності. Від простих односторінкових сайтів до складних інтернет-магазинів, CRM систем з інтеграцією 1С та телефонії. Досвід розробників підтверджено сертифікатами від вендора.
Показано 1 з 1 послугУсі 1626 послуг
Налаштування захисту контенту від парсингу 1С-Бітрікс
Проста
~1 робочий день
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Розробка на базі Бітрікс, Бітрікс24, 1С для компанії Development of an Online
    585
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Розробка на базі 1С Підприємство для компанії МИРСАНБЕЛ
    751
  • image_crm_dolbimby_434_0.webp
    Розробка сайту на CRM Бітрікс24 для компанії DOLBIMBY
    657
  • image_crm_technotorgcomplex_453_0.webp
    Розробка на базі Бітрікс24 для компанії ТЕХНОТОРГКОМПЛЕКС
    989

Налаштування захисту контенту від парсингу 1С-Бітрікс

Конкуренти парсять каталог: збирають ціни, описи, характеристики, використовують для моніторингу або копіюють на власний сайт. Повний захист неможливий — якщо людина може бачити дані, програма теж може. Завдання — зробити парсинг достатньо дорогим, щоб він втратив економічний сенс.

Ешелонований захист

Захист будується в кілька шарів. Кожен шар ловить різний тип парсерів.

Шар 1 — nginx rate limiting. Перший рубіж, не навантажує PHP:

# /etc/nginx/conf.d/rate-limit.conf

# Зона для обмеження по IP
limit_req_zone $binary_remote_addr zone=catalog:10m rate=20r/m;
limit_req_zone $binary_remote_addr zone=search:10m  rate=5r/m;

# Застосовуємо до сторінок каталогу
location /catalog/ {
    limit_req zone=catalog burst=40 nodelay;
    limit_req_status 429;
    # ... інші директиви
}

location /search/ {
    limit_req zone=search burst=10 nodelay;
    limit_req_status 429;
}

Шар 2 — аналіз User-Agent. У 1С-Бітрікс через init.php:

// /local/php_interface/init.php
$blockedAgents = [
    'python-requests', 'scrapy', 'curl/', 'wget/',
    'Go-http-client', 'Java/', 'PhantomJS', 'Headless',
];

$ua = strtolower($_SERVER['HTTP_USER_AGENT'] ?? '');
foreach ($blockedAgents as $bad) {
    if (str_contains($ua, strtolower($bad))) {
        header('HTTP/1.1 403 Forbidden');
        exit;
    }
}

Примітивні парсери відсіюються одразу. Просунуті підміняють User-Agent — використовуємо наступні шари.

Шар 3 — поведінковий аналіз. Реальні користувачі не запитують 200 сторінок каталогу за 5 хвилин. Лічильник запитів по IP в Redis:

namespace Local\Security;

class RateLimiter
{
    private const WINDOW   = 300;  // 5 хвилин
    private const LIMIT    = 100;  // запитів на каталог
    private const BAN_TIME = 3600; // бан на годину

    public static function check(string $ip): bool
    {
        $redis = \Bitrix\Main\Data\Cache::createInstance();
        // Спрощено: використовуємо кеш 1С-Бітрікс
        $key    = 'ratelimit_catalog_' . md5($ip);
        $count  = (int)(\Bitrix\Main\Application::getInstance()
                        ->getManagedCache()->get($key) ?? 0);

        if ($count > self::LIMIT) {
            // Логуємо і блокуємо
            self::banIp($ip);
            return false;
        }

        \Bitrix\Main\Application::getInstance()->getManagedCache()->set(
            $key,
            $count + 1,
            self::WINDOW
        );

        return true;
    }

    private static function banIp(string $ip): void
    {
        // Додаємо до таблиці банів 1С-Бітрікс (b_stop_list)
        \CStopList::Add([
            'SITE_ID'   => SITE_ID,
            'IP_ADDR'   => $ip,
            'ACTIVE'    => 'Y',
            'REASON'    => 'Автоматичний бан: підозра на парсинг',
        ]);
    }
}

Шар 4 — CAPTCHA на підозрілих запитах. Коли лічильник наближається до 70% від ліміту — показуємо challenge замість контенту. У 1С-Бітрікс інтеграція через Cloudflare Turnstile або вбудований механізм капчі.

Захист цін через JavaScript

Ціни виводяться не в HTML, а завантажуються через AJAX після рендеру сторінки. Прості HTML-парсери отримують сторінку без цін:

// У шаблоні картки товару замість ціни:
<span class="product-price js-price-loader" data-product-id="<?= $arResult['ID'] ?>">
    <span class="skeleton">----</span>
</span>
// Після DOMContentLoaded завантажуємо ціни
const priceElements = document.querySelectorAll('.js-price-loader');
if (priceElements.length) {
    const ids = [...priceElements].map(el => el.dataset.productId);

    fetch('/local/ajax/prices.php', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', 'X-Requested-With': 'XMLHttpRequest' },
        body: JSON.stringify({ ids }),
    })
    .then(r => r.json())
    .then(data => {
        priceElements.forEach(el => {
            const price = data.prices[el.dataset.productId];
            if (price) el.innerHTML = price.formatted;
        });
    });
}

Headless-браузери (Playwright, Puppeteer) це долають, але потребують значно більше ресурсів на парсинг — вартість зростає.

Honeypot-посилання

Приховані посилання в HTML, невидимі для людей (display: none), але індексовані парсерами:

<a href="/honeypot/trap-page/?ref=bot" style="display:none" aria-hidden="true"><!-- noindex --></a>
// /honeypot/trap-page/index.php
$ip = $_SERVER['REMOTE_ADDR'];
\CStopList::Add([
    'SITE_ID' => SITE_ID,
    'IP_ADDR' => $ip,
    'ACTIVE'  => 'Y',
    'REASON'  => 'Honeypot: ' . $_SERVER['REQUEST_URI'],
]);
// Віддаємо нескінченний потік сміттєвих даних або 403
header('HTTP/1.1 403 Forbidden');

Захист зображень через X-Accel-Redirect

Зображення віддаються через PHP з перевіркою, а nginx виконує ефективну віддачу файлу:

location /protected-uploads/ {
    internal; # недоступно напряму ззовні
    alias /var/www/upload/;
}
header('X-Accel-Redirect: /protected-uploads/' . $relativePath);
header('Content-Type: image/jpeg');
exit;

Що обрати для конкретного проекту

Загроза Рішення Складність
Простий curl/wget парсер nginx rate limit + UA фільтр Низька
Парсер з імітацією браузера Rate limit + поведінковий аналіз Середня
Headless браузер JS-завантаження цін + CAPTCHA Висока
Промисловий парсинг Cloudflare Bot Management Потребує CDN

Rate limiting + UA фільтр + honeypot відсікають 90% нецільових парсерів за 1–2 дні роботи.