---
title: "Защита от скрапинга: честные пределы Colly"
description: "Защита от парсинга: robots.txt и Disallow, лимиты по IP, капчи и JS-рендеринг — что умеет colly, чего не умеет никогда и где у скрапера красная линия."
course: "Colly: парсинг и веб-скрапинг на Go"
url: "https://golangmaster.ru/courses/colly/lessons/22-antibot-zaschita/"
published: "2026-09-19"
updated: "2026-09-21"
minutes: 18
---

# Защита от скрапинга: честные пределы Colly

*Курс «Colly: парсинг и веб-скрапинг на Go», урок 22 из 25. ~18 минут. Обновлено 21.09.2026. Источник: https://golangmaster.ru/courses/colly/lessons/22-antibot-zaschita/*

Защита от парсинга — это ступени, по которым сайт встречает автоматический трафик: файл robots.txt, лимиты по IP, капчи, JS-рендеринг, поведенческий анализ. Colly честно останавливается перед несколькими из них, и лучше узнать про эти пределы из урока, чем из недели выброшенного кода. Разберём, как читать robots.txt и почему colly сама его не проверяет, что библиотека не умеет в принципе, какие есть альтернативы и где проходит красная линия, за которую вежливый скрапер не заходит.

Сценарий, после которого обычно пишут такой урок: вчера скрипт собирал каталог, сегодня тот же код получает 403, а вместо списка товаров — страницу-заглушку с предложением доказать, что вы не робот. В коде не изменилось ничего, изменилась реакция сайта. За этим стоит простая механика: у сайта есть инструменты защиты от парсинга, от дешёвых и пассивных до дорогих и агрессивных, и каждый следующий уровень обхода стоит вам больше усилий — не всегда разрешённых. Задача урока — не учить пролезать, а нарисовать карту: что делает сайт, что видит colly, что остаётся за пределами библиотеки и какие ответы законны в каждом случае. Карта нужна даже тому, кто скрапит только учебные витрины: однажды витрина кончится, а привычки останутся.

### robots.txt: файл, с которого начинается вежливость

Robots.txt — текстовый файл в корне сайта: https://site.example/robots.txt. Его читают роботы, чтобы понять, куда ходить нельзя. Синтаксис элементарный: блоки User-agent задают, к кому относится правило, строки Disallow перечисляют запрещённые префиксы путей, Allow — исключения из запрета, Crawl-delay просит держать паузу между запросами, звёздочка в пути означает любой фрагмент. Детали сопоставления правил у разных роботов различаются, поэтому не усложняйте: увидели свой путь в Disallow — этот путь не трогаем, и всё. Crawl-delay — не пожелание, а условие доступа: если сайт просит пять секунд паузы, LimitRule с Delay из урока про [лимиты и параллелизм](/courses/colly/lessons/10-limitrule/) — минимальная цена входа. Отдельный честный вопрос: robots.txt — это закон или конвенция? Юридически — не закон, технически — просьба, этически — публичное заявление владельца о том, куда он автоматический трафик не пускает. Для поисковых роботов документ обязателен де-факто, для скрапера это самый дешёвый способ не оказаться в списке врагов.

### Как выглядит robots.txt изнутри

```go
# https://shop.example/robots.txt

User-agent: *
Disallow: /cart/
Disallow: /search?
Disallow: /*?sort=
Crawl-delay: 5

User-agent: Googlebot
Disallow:
```

Первый блок — для всех роботов: закрыты корзина, поиск и сортировки, между запросами просят пять секунд паузы. Пустой Disallow у Googlebot означает «этот робот ходит свободно»: разделение по агентам работает именно так — правило берётся из блока своего User-agent, а не складывается со всеми. Для скрапера практический вывод: ваш трафик обычно попадает под первую группу, и спорить с ней — осознанное решение с последствиями.

### Почему colly сама не проверяет robots.txt

Colly — HTTP-клиент с колбеками, и ничего о правилах она не знает: за robots.txt не ходит, пути с ним не сверяет, при нарушении не ругается. Решение остаётся за вами, и это не недоработка, а разделение ответственности: что считать запрещённым, библиотека решить не может. Минимальная дисциплина — руками: отдельным Visit забрать файл из корня, прочитать строки, собрать префиксы Disallow и проверять их перед каждым Visit и перед каждой ссылкой из AbsoluteURL. Это пара десятков строк и один слайс, а экономит оно и нервы, и репутацию. Дальше по цепочке — обычные механизмы курса: AllowedDomains не выпускает за чужие домены, MaxDepth не даёт обходу разбегаться вглубь, LimitRule держит темп — всё это разбирали в уроке про [URL-фильтры и глубину](/courses/colly/lessons/18-url-filtry/). Проверить поведение можно только локально: песочница сети не умеет, а живой сайт — лучший инспектор.

### Вежливость техническая: кэш, таймауты, темп

Часть вежливости не про обход защиты, а про экономию чужих ресурсов. CacheDir кэширует ответы на диск — повторный запуск разработки не дёргает сайт второй раз, механика в уроке про [кэш и офлайн-режим](/courses/colly/lessons/17-kesh-skrepera/). SetRequestTimeout не вешает соединение на минуты, если сайт притворяется медленным. Delay и RandomDelay в LimitRule размазывают запросы, чтобы профиль вашего трафика не выглядел как очередь роботов. Ничего из этого не даёт «невидимость» — и не ставит такой цели: это гигиена, которая делает обход дешевле и для сайта, и для вас. Забавно, что те же настройки косвенно снижают и шанс попасть под лимиты по IP: меньше запросов в секунду — меньше поводов для реакции.

### Ступени защиты: реакция сайта и ответ скрапера

| Защита | Как видит её скрапер | Законный ответ |
| --- | --- | --- |
| robots.txt | файл с Disallow-правилами в корне сайта | прочитать и соблюдать: пути из Disallow не трогать |
| Лимиты по IP | 429 и 403, обрывы соединений, временная блокировка адреса | снизить темп: Delay и RandomDelay в LimitRule, один воркер вместо десяти |
| Капча | страница с проверкой «вы человек» вместо контента | остановиться и не повторять: капчи colly не решает и решать не будет |
| JS-рендеринг | в HTML пустой div, данные рисует браузер | искать JSON-эндпоинт или переходить на браузерный движок |
| Поведенческий анализ | реакция на ровные интервалы, странные заголовки, отсутствие сессий | вести себя как честный клиент или отказаться от обхода |

### Чего colly не умеет: исполнять JavaScript

Colly работает с тем, что прислал сервер, и не исполняет JavaScript — это её главный предел. Для сайтов, отрисованных на JS, это значит конкретное: HTML-ответ содержит пару тегов и пустой контейнер вроде <div id='root'></div>, а товары рисует браузер уже после загрузки скриптов. OnHTML('.product') в такой ситуации молчит — элементов в ответе нет. Типичная ошибка новичка — диагностика через инспектор: открыть браузер, увидеть в инспекторе карточки и решить, что селектор рабочий. Инспектор показывает DOM после исполнения скриптов; colly же получает исходник. Проверяйте через просмотр исходного кода страницы (Ctrl+U): если карточек в исходнике нет, colly их не увидит. Здесь часто спасает приём из [прошлого урока про JSON вместо HTML](/courses/colly/lessons/21-api-json-endpointy/) — данные, которые рисует скрипт, кто-то же ему отдал.

### Альтернативы: chromedp и Rod

Когда без JavaScript никак, Go-разработчик берёт браузерный движок: chromedp или Rod. Оба управляют настоящим Chrome через DevTools Protocol: открывают страницу, ждут появления элементов, скроллят, кликают и отдают DOM уже после исполнения скриптов. Цена ясна: процесс браузера в памяти, время загрузки в разы больше, зависимости тяжелее, а скрапер превращается в управление браузером со всеми его капризами — версиями, ожиданиями, таймаутами. Поэтому правило такое: сначала эндпоинт, потом colly, и только затем браузер — как последний аргумент, а не первый инструмент. В этом курсе мы остаёмся на colly: связка с браузерным движком — отдельный мир со своими ошибками и стоит отдельных недель, смешивать слои стоит осознанно и по одному. И заметьте асимметрию: colly управляется одной строкой NewCollector, браузеру нужен отдельный процесс и ритуал запуска — разница в цене поддержки примерно такая же.

> **Красная линия курса.** Обход капчи и взлом технических блокировок — то, чем этот курс не занимается и что нормой не считает. В сети найдутся сотни сервисов распознавания и рецептов обхода; здесь их не будет. Если сайт активно сопротивляется — ставит капчи, банит адреса, прячет всё за браузерными проверками, — это не задача «победить защиту», это сигнал: данные владельцем раздаются иначе. Ищите партнёрскую выгрузку, прайс-ленту, официальное API или напишите владельцу: письмо дешевле недели войны и работает чаще, чем кажется.

### Три вопроса перед запуском: ToS, персональные данные, объём

Правовая часть складывается из трёх вопросов, и ни один не отменяется тем, что «данные же публичные». Первый: условия использования сайта — ToS. Многие прямо запрещают автоматический сбор; нарушение — риск для отношений с площадкой, а иногда и для дела в целом. Второй: персональные данные. Имена, телефоны, отзывы пользователей, содержимое личных кабинетов — собирать их скрапером самая сомнительная затея из возможных; законодательство о персональных данных различается по странам и везде строже, чем правила про цены. Третий: объём копируемого. Список цен и названий для сравнения — обычная практика; копирование статей, фотографий и каталогов целиком — уже использование чужого контента со всеми последствиями. Это не юридическая консультация: законы и судебная практика меняются, а при серьёзных объёмах вопрос стоит задать юристу, а не поисковику.

### Проверка: 403 и colly

**Вопрос:** Сайт начал отвечать 403. Что по умолчанию произойдёт внутри colly?

- OnHTML разберёт страницу-заглушку как обычно
- ✅ Сработает OnError, а HTML-разбор ошибочного ответа colly по умолчанию не делает
- Программа упадёт с паникой
- Colly автоматически повторит запрос

Ответ с ошибочным статусом colly по умолчанию не прогоняет через OnHTML — для этого существует отдельная опция ParseHTTPErrorResponse. Зато OnError получает каждый неудачный запрос: статус, тело и причину. Логируйте там и решайте, что делать: повтор с задержкой, остановка или сигнал человеку.

### Пустой div из SPA

```go
c := colly.NewCollector()

c.OnHTML(".product", func(e *colly.HTMLElement) {
        fmt.Println(e.Text)
})

// сервер вернул:
// <html><body><div id='root'></div></body></html>

c.Visit("https://spa.example.com/")
```

**Что выведет программа?**

- Напечатает пустую строку
- ✅ Ничего не напечатает: элементов .product в ответе нет
- Вернёт ошибку от Visit
- Запаникует внутри колбека

Колбек OnHTML вызывается только на найденные элементы. В ответе их нет — JavaScript colly не исполняет, и контейнер останется пустым. Visit завершится без ошибки: со стороны HTTP всё хорошо, 200 OK. Именно так выглядят SPA-сайты для colly — тихий ноль вместо данных.

### Соберите вежливый коллектор

Восстановите настройку: домены и лимиты темпа.

```go
c := colly.NewCollector(
        colly.___("books.toscrape.com"),
)

c.___([]*colly.LimitRule{{
        DomainGlob:  "*books.toscrape.com",
        Delay:       2 * time.Second,
        RandomDelay: 1 * time.Second,
        Parallelism: 1,
}})
```

Подсказка: Первое — опция конструктора, ограничивающая домены; второе — метод, принимающий срез LimitRule.

Правильные ответы в пропусках: `AllowedDomains`, `Limit`

### Скелет вежливого скрапера

Соберите порядок строк: настройки, темп, обработчики, запуск и ожидание.

Правильный порядок строк:

1. `package main`
2. `import "github.com/gocolly/colly/v2"`
3. `c := colly.NewCollector(colly.AllowedDomains("site.example"))`
4. `c.Limit([]*colly.LimitRule{{DomainGlob: "*site.example", Delay: 3 * time.Second}})`
5. `c.OnHTML(".product", func(e *colly.HTMLElement) { /* поля товара */ })`
6. `c.OnError(func(r *colly.Response, err error) { log.Println(r.StatusCode, err) })`
7. `c.Visit("https://site.example/catalog")`
8. `c.Wait()`

### Карточки: защита и пределы

- **robots.txt** — Файл в корне сайта с правилами для роботов: User-agent, Disallow, Allow, Crawl-delay. Colly его не читает — проверка на совести скрапера.
- **Disallow** — Правило robots.txt, запрещающее роботу пути с указанным префиксом: Disallow: /cart/. Увидели — не ходите.
- **429 Too Many Requests** — Статус «слишком много запросов»: сайт ограничивает темп по IP. Ответ вежливого скрапера — уменьшить Parallelism и увеличить Delay в LimitRule.
- **JS-рендеринг** — Схема, при которой данные рисует браузер из JavaScript, а HTML содержит пустой контейнер. Colly такой контент не видит.
- **chromedp** — Библиотека управления Chrome через DevTools Protocol: исполняет JavaScript и отдаёт готовый DOM. Тяжелее colly, применяется когда без JS никак.
- **ToS** — Terms of Service — условия использования сайта. Автоматический сбор часто запрещён прямо; нарушение — риск не только технический.

### Если сайт сопротивляется — это ответ

Соберём позицию курса вместе. Обход капчи и технических блокировок — красная линия, за которой мы не заходим: ни в этом уроке, ни в итоговом проекте. Повторы с задержкой после единичной ошибки — это вежливость, и ей занимается урок про [ошибки и повторы](/courses/colly/lessons/16-oshibki-retry/); прокси для честного распределения нагрузки обсуждались в уроке про [прокси](/courses/colly/lessons/15-proxy/) — но всё это про темп, а не про взлом замка. Если же сайт ставит капчи, банит адреса и прячет данные за браузерными проверками, он ответил: здесь автоматическому сбору не рады. Законный ход — спросить данные у владельца: партнёрские программы, выгрузки и официальные API существуют у большинства площадок, и письмо с внятным описанием задачи работает чаще, чем любой обход. Следующий урок — про [тестирование скрапера на фикстурах](/courses/colly/lessons/23-testirovanie-skrepera/): вернёмся к коду, который не зависит от чужой обороны.

## Коротко: что запомнить

- robots.txt — файл в корне сайта с Disallow-правилами; colly его не проверяет, решение на совести скрапера.
- Ступени защиты нарастают: лимиты по IP, капчи, JS-рендеринг, поведенческий анализ — каждая следующая дороже для скрапера.
- Colly не исполняет JavaScript: SPA отдаёт пустой контейнер, и OnHTML молчит — инспектор браузера об этом не предупредит.
- Когда без JS никак — chromedp или Rod: настоящий браузер видит скрипты, но стоит памяти и времени.
- По умолчанию ошибочные статусы не доходят до OnHTML: ловите их в OnError, ParseHTTPErrorResponse меняет поведение сознательно.
- Обход капчи и блокировок — красная линия курса; активное сопротивление сайта — повод спросить данные у владельца.

## Домашнее задание

Откройте robots.txt трёх сайтов, где бываете, и найдите там Disallow и Crawl-delay. Затем соберите скрапер с AllowedDomains, LimitRule с задержкой не меньше запрошенной и OnError, который логирует статусы. Направьте его на страницу из запрета robots.txt и убедитесь, что ваш код умеет туда не ходить — фильтр по префиксам пишется в двадцать строк.

## Вопросы и ответы по уроку

### Законен ли парсинг сайтов?

Зависит от данных, юрисдикции и способа: публичные страницы с уважением к robots.txt и нагрузке — обычная практика, а обход авторизации, персональные данные и копирование защищённого контента создают правовые риски. Три ориентира из урока: ToS, персональные данные, объём копируемого.

### Почему colly не читает robots.txt автоматически?

Colly — HTTP-клиент с колбеками и ничего не решает за вас о допустимости путей. Проверка делается вручную: забрать файл, собрать префиксы Disallow и сверять их перед каждым Visit. Это дисциплина скрапера, а не функция библиотеки.

### Как понять, что сайт рендерится на JavaScript?

Откройте исходный код страницы (Ctrl+U), а не инспектор: если нужных элементов в исходнике нет, а в инспекторе есть — данные рисует скрипт. Colly увидит пустой контейнер; ищите JSON-эндпоинт или берите браузерный движок вроде chromedp.
