Схема «поднял Firecrawl в Docker, натравил на список доменов, получил markdown для RAG» работает ровно до первой тысячи страниц. Дальше приходят два счёта. Первый — от анти-ботов: часть доменов начинает отдавать 403 вместо контента, и в базе знаний появляются дыры, о которых вы узнаёте, когда ассистент отвечает «в предоставленных материалах нет информации». Второй счёт — за трафик: краулер честно тянет каждую картинку и каждый шрифт, которые в итоговый markdown всё равно не попадут.
Разберём, как подключить прокси к трём самым ходовым LLM-краулерам 2026 года — Firecrawl, Crawl4AI и Crawlee — и как настроить их так, чтобы прокси работал только там, где он нужен, а не жёг гигабайты на каждой странице.
Для кого этот гайд
Если вы собираете корпус документов для RAG, наполняете внутреннюю базу знаний, строите дата-пайплайн для дообучения или просто регулярно выкачиваете сотни доменов — это ваш случай. Все три инструмента ниже в конфигурации по умолчанию ходят с IP вашего сервера и грузят страницу целиком. Оба этих умолчания нужно менять.
Масштаб проблемы понятен по цифрам популярности: у Firecrawl на момент публикации около 170 тысяч звёзд на GitHub (лицензия AGPL-3.0), у Crawl4AI — порядка 79 тысяч, у Crawlee от Apify — около 25 тысяч. Это уже не нишевые эксперименты, а стандартный инструментарий, и анти-бот-системы знают их поведение не хуже вашего.
Счёт первый: 403 вместо контента
Ключевая ошибка при сборе корпуса — считать, что краулер отработал успешно, если он не упал. Firecrawl и Crawl4AI на заблокированной странице возвращают не исключение, а результат: страницу-заглушку анти-бота, страницу с проверкой браузера или короткий текст об отказе в доступе. Формально это валидный markdown, он спокойно ложится в векторную базу и живёт там до первого запроса пользователя.
Поэтому первое, что нужно сделать до всякой настройки прокси, — добавить контроль качества результата. Минимальный вариант: отбраковывать документы короче некоторого порога (для типичной контентной страницы разумно 500–800 символов текста) и отдельно ловить характерные маркеры в тексте — упоминания проверки соединения, включённого JavaScript, «Access denied». Такие документы отправляются не в базу, а в очередь на повторный обход — уже через прокси.
Счёт второй: гигабайты, которые вы выбрасываете
Здесь помогает арифметика. По данным Web Almanac от HTTP Archive за 2025 год, медианная главная страница весит примерно 2,86 МБ на десктопе и 2,56 МБ на мобильных. Из них на изображения приходится около 1 059 КБ на главных страницах и 911 КБ на внутренних, на JavaScript — 697 КБ и 632 КБ соответственно. То есть картинки — самая тяжёлая категория, примерно треть веса страницы.
А теперь вспомните, что вы делаете с результатом. Вы конвертируете страницу в markdown и режете на чанки для эмбеддингов. Изображения в этот пайплайн не попадают вообще — в лучшем случае от них остаётся строчка с alt-текстом. Видео, шрифты, аналитические скрипты, рекламные пиксели — тоже мимо.
Если гнать обход через резидентный прокси с оплатой за гигабайт, вы буквально платите за доставку данных, которые выбрасываете на следующем шаге пайплайна. На корпусе в 100 тысяч страниц разница между «тянуть всё» и «тянуть только HTML и текст» измеряется не процентами, а разами. Точная экономия зависит от тематики сайтов: медиа и e-commerce тяжелее документации и блогов.
Шаг 1. Эскалация вместо «прокси на всё»
Главный архитектурный приём, который экономит больше всего: не пускать весь трафик через прокси. Большая часть доменов при сборе базы знаний — документация, блоги, справочные сайты, госпорталы — отдаёт контент напрямую и не блокирует никого. Прокси нужен меньшинству.
Правильная схема — многоуровневая эскалация: сначала прямой запрос, при признаках блокировки — переход на следующий уровень. Причём это не самописный костыль, оба взрослых фреймворка умеют так из коробки.
В Crawlee для этого есть tieredProxyUrls. Уровни перечисляются от дешёвого к дорогому, и краулер сам поднимается вверх при блокировках, а затем периодически пробует вернуться на нижний уровень:
const proxyConfiguration = new ProxyConfiguration({
tieredProxyUrls: [
[null],
['http://user:pass@datacenter-proxy:8080'],
['http://user:pass@residential-proxy:8000'],
]
});
Важный нюанс из документации: tieredProxyUrls работает только при использовании через экземпляр краулера. Прямые вызовы newUrl() дадут неожиданный результат.
В Crawl4AI похожий механизм появился в версии 0.8.5 и живёт в актуальной ветке (последний релиз на момент публикации — v0.9.2 от 15 июля 2026 года). Называется он proxy escalation и настраивается прямо в CrawlerRunConfig: трёхуровневый детект блокировки — известные вендоры анти-ботов, общие индикаторы блока и проверка структурной целостности страницы — плюс автоматический ретрай по цепочке прокси.
from crawl4ai import CrawlerRunConfig
from crawl4ai.async_configs import ProxyConfig
config = CrawlerRunConfig(
proxy_config=[ProxyConfig.DIRECT, ProxyConfig(server="http://my-proxy:8080")],
max_retries=2,
)
Обратите внимание на ProxyConfig.DIRECT первым элементом — это и есть «сначала попробуй без прокси».
Шаг 2. Подключение прокси в каждом инструменте
Дальше — конкретика по настройке. Порядок действий одинаковый: сначала прокси, потом отсечение лишнего трафика, потом проверка.
- Firecrawl (self-hosted). Прокси задаётся тремя переменными окружения, которые прокидываются в Playwright:
PROXY_SERVER,PROXY_USERNAME,PROXY_PASSWORD. Прописываются в.envдляapps/api; в комментарии к ним разработчики прямо пишут, что вместо статического адреса можно указать прокси-сервис, который ротирует IP на каждый запрос. - Crawl4AI. Прокси живёт в
BrowserConfig, в полеproxy_config— это объектProxyConfigили словарь с полямиserver,username,password. Одна конфигурация браузера на всю сессию краулинга; отдельныйCrawlerRunConfigпередаётся на каждый вызовarun(). - Crawlee. Класс
ProxyConfigurationс опциейproxyUrls— список адресов, по которому библиотека идёт по кругу (round-robin). Значениеnullв списке означает «без прокси». Интеграция сквозная:HttpCrawler,CheerioCrawler,JSDOMCrawler,PlaywrightCrawler,PuppeteerCrawler. - Точечные правила. Если известно, какие домены блокируют, а какие нет, в Crawlee есть
newUrlFunction— своя логика выбора прокси на основе URL запроса. Для белых доменов возвращаетеnull, для остальных — адрес прокси. Это самый дешёвый вариант, когда список целей стабилен. - Проверка. Перед боевым прогоном пропустите через настроенный краулер страницу, отдающую ваш внешний IP, и убедитесь, что видите адрес прокси, а не сервера. Три строчки, которые экономят день разбирательств.
Шаг 3. Отрезать всё, что не станет текстом
Когда прокси подключён, включайте экономию трафика — иначе счёт за гигабайты придёт быстрее, чем соберётся корпус.
В Firecrawl за это отвечает переменная BLOCK_MEDIA. В официальном примере конфигурации к ней стоит буквальный комментарий: установите, если хотите блокировать медиа-запросы, чтобы сэкономить полосу прокси. Это самый быстрый способ убрать основную статью расходов.
В Crawl4AI аналогичные рычаги живут в BrowserConfig: text_mode отключает изображения и ускоряет текстовый обход, light_mode выключает часть фоновых функций браузера, avoid_css блокирует загрузку CSS. Их можно комбинировать. Для сбора корпуса под RAG это почти всегда правильный набор — вёрстка вам не нужна, нужен текст.
В Crawlee логика другая: если контент отдаётся в HTML, используйте CheerioCrawler или HttpCrawler вместо браузерных. Обычный HTTP-запрос вместо полноценного рендера — это не просто экономия трафика, это другой порядок расходов. Браузерные краулеры (PlaywrightCrawler, PuppeteerCrawler) оставляйте только для страниц, которые без JavaScript не собираются.
Подводные камни
Сессии против ротации. Смена IP на каждый запрос сама по себе выглядит подозрительно и ломает многошаговые сценарии — пагинацию, переходы внутри одного домена. В Crawlee каждый вызов newUrl() сцепляет прокси с объектом Session, и ротируются они вместе с отпечатками браузера и заголовками. Не разрывайте эту связку вручную.
Медиа отключены, но контент пропал. Часть сайтов ленивой загрузкой подтягивает не только картинки, но и текст. После включения text_mode или BLOCK_MEDIA обязательно прогоните контрольную выборку из 20–30 страниц и сравните объём текста с эталоном.
Ретраи без потолка. Эскалация по уровням прокси означает, что одна упрямая страница может быть скачана трижды — и все три раза оплачена. Ограничивайте max_retries и заводите список доменов, которые после N неудач исключаются из обхода совсем.
Robots.txt и правовая рамка. Сбор данных для обучения и RAG в 2026 году регулируется жёстче, чем пару лет назад, — от требований к раскрытию источников до механизмов отказа от text and data mining. Проверьте, что ваш пайплайн уважает эти сигналы, до того как он отработает на сотне тысяч страниц.
Какой тип прокси брать под RAG-пайплайн
Ответ зависит от того, на каком уровне эскалации вы находитесь.
- Нулевой уровень — без прокси. Документация, opensource-проекты, госсайты, большинство корпоративных блогов. Здесь IP сервера работает нормально, и платить не за что.
- Средний уровень — датацентр-прокси. Быстрые и дешёвые, годятся против простого rate limiting и региональных ограничений. При сборе больших корпусов это рабочая лошадка: когда объём измеряется сотнями гигабайт, разница в цене за гигабайт становится главным фактором.
- Верхний уровень — резидентные прокси. Для доменов за серьёзной анти-бот-защитой, где датацентр-подсети отсеиваются на входе. Именно поэтому их нельзя ставить уровнем по умолчанию — оплата за гигабайт превращает каждую лишнюю картинку в строку расходов.
Прежде чем строить пайплайн, стоит честно посчитать экономику: мы разбирали полную стоимость парсинга миллиона страниц с учётом веса страниц, ретраев и скрытых расходов. И отдельный вопрос, который полезно задать до того, как писать первую строчку кода: а нужен ли вообще обход — в разборе официального API против готовых датасетов и парсинга видно, что для части источников готовые данные выходят дешевле собственного краулера.
Вывод
Прокси в LLM-краулере — это не переключатель «вкл/выкл», а трёхуровневая схема. Прямой запрос как уровень по умолчанию, датацентр-прокси на среднем, резидентные — только для доменов, которые иначе не берутся. Плюс жёсткое отсечение медиа, потому что вы собираете текст, а платите за байты.
Порядок работ простой: сначала контроль качества результата (иначе вы не узнаете, что половина корпуса — это страницы-заглушки), потом эскалация прокси средствами самого фреймворка, потом экономия трафика. В таком порядке — и корпус получится полным, и счёт предсказуемым.
