- Хост
- gw.prokso.com
- Порт
- 823 HTTP · 824 SOCKS5 — новый IP на каждый запрос · 10000–20000 фиксированный IP (sticky-сессия), HTTP(S) и SOCKS5
- Логин и пароль
- в кабинете, на странице плана
Готовые строки в нужном формате генерирует кабинет: выберите страну, тип IP и протокол.
- Хост — gw.prokso.com, порты 823 (HTTP), 824 (SOCKS5), 10000–20000 (фиксированный IP, HTTP или SOCKS5)
- Логин и пароль — в кабинете на странице плана
- Проверяйте IP в ответе самого запроса через прокси: страница «Мой IP» в браузере ваш скрипт не проверяет
Пошаговая инструкция, как подключить прокси Prokso в Crawl4AI. Займёт несколько минут.
Шаг 1. Возьмите данные прокси в кабинете
Откройте план и скопируйте хост gw.prokso.com, порт, логин и пароль. Порт 823 — HTTP, 824 — SOCKS5 (оба дают новый IP на каждый запрос); порты 10000–20000 — фиксированный IP до 120 минут, работают и как HTTP, и как SOCKS5 (каждый порт — отдельный адрес). Страну задают в логине: логин__cr.ua.
Шаг 2. Установите Crawl4AI
pip install -U crawl4ai, затем crawl4ai-setup — эта команда ставит браузер, которым Crawl4AI открывает страницы. Проверить установку можно командой crawl4ai-doctor. Инструкция написана для версии 0.9.5.
import asyncio
from crawl4ai import AsyncWebCrawler, BrowserConfig, CrawlerRunConfig, ProxyConfig
run_config = CrawlerRunConfig(
proxy_config=ProxyConfig(
server="http://gw.prokso.com:823",
username="ЛОГИН",
password="ПАРОЛЬ",
)
)
async def main():
async with AsyncWebCrawler(config=BrowserConfig()) as crawler:
result = await crawler.arun(url="https://api.ipify.org", config=run_config)
print(result.success, result.markdown)
asyncio.run(main())Сохраните код в файл, например crawl.py, и запустите командой python crawl.py.
Шаг 3. Передайте прокси в CrawlerRunConfig
Создайте ProxyConfig с адресом http://gw.prokso.com:823 и отдельными полями username и password и передайте его параметром proxy_config в CrawlerRunConfig. Именно так советует официальная документация: прокси задаётся для каждого запуска arun, а параметр прокси в BrowserConfig там помечен как устаревший.
Шаг 4. Логин, пароль и страна
Логин и пароль возьмите из генератора в кабинете. Отдельные поля username и password удобнее адреса с паролем: спецсимволы не нужно кодировать. Страну задаёт логин: ЛОГИН__cr.de — страницы будут открываться с немецких адресов. Для браузера берите схему http://: логин и пароль Chromium передаёт только HTTP-прокси.
Шаг 5. Выберите порт под задачу
Порт 823 даёт новый IP на каждый запрос — он подходит для разового сбора отдельных страниц. Если краулер проходит несколько страниц одного сайта в одной сессии (вход в аккаунт, корзина, пагинация), возьмите фиксированный порт 10000–20000: сайт связывает сессию с IP, и смена адреса посреди неё выглядит подозрительно. Адрес на порту держится от 1 до 120 минут, время настраивается в кабинете.
import asyncio
from crawl4ai import AsyncWebCrawler, BrowserConfig, CrawlerRunConfig, ProxyConfig
def sticky(port):
return CrawlerRunConfig(proxy_config=ProxyConfig(
server=f"http://gw.prokso.com:{port}",
username="ЛОГИН",
password="ПАРОЛЬ",
))
async def main():
async with AsyncWebCrawler(config=BrowserConfig()) as crawler:
for port in (10001, 10002):
config = sticky(port)
for _ in range(2):
result = await crawler.arun(url="https://api.ipify.org", config=config)
print(port, result.markdown)
asyncio.run(main())Сохраните код в файл, например crawl.py, и запустите командой python crawl.py.
Шаг 6. Несколько сессий — свой порт на каждую
Поскольку прокси живёт в CrawlerRunConfig, для каждой сессии можно собрать отдельную конфигурацию со своим фиксированным портом. В примере два порта: запросы через один порт возвращают тот же IP, через разные — разные адреса.
Шаг 7. Проверьте вывод
Запустите пример: краулер открывает https://api.ipify.org и печатает IP, который видит сайт. Это должен быть адрес прокси, а не ваш. Ошибка 407 означает неверный логин или пароль либо закончившийся трафик на плане. Страница «Мой IP» в вашем браузере здесь не поможет: скрипт запускает собственный браузер, а ваш идёт напрямую.
arun_many и фиксированный порт на каждый воркер
arun_many() берёт весь список адресов и открывает страницы параллельно через диспетчер. Прокси живёт в CrawlerRunConfig, поэтому с одной конфигурацией все страницы идут через один прокси: на порту 823 каждая получает новый IP. Если страницы должны идти с фиксированного набора адресов, разделите список и дайте каждой части свой фиксированный порт.
import asyncio
import os
from crawl4ai import (AsyncWebCrawler, BrowserConfig, CacheMode, CrawlerRunConfig,
MemoryAdaptiveDispatcher, ProxyConfig, RateLimiter)
PASSWORD = os.environ["PROKSO_PASSWORD"] # пароль не храним в коде
URLS = [f"https://example.de/catalog?page={n}" for n in range(1, 31)]
PORTS = [10001, 10002, 10003] # один фиксированный порт = один IP на воркер
def config_for(port):
return CrawlerRunConfig(
proxy_config=ProxyConfig(
server=f"http://gw.prokso.com:{port}",
username="ЛОГИН__cr.de",
password=PASSWORD,
),
cache_mode=CacheMode.ENABLED, # не загружать повторно то, что уже есть в кэше
page_timeout=90000, # миллисекунды
)
async def worker(crawler, port, urls):
dispatcher = MemoryAdaptiveDispatcher(
max_session_permit=2,
rate_limiter=RateLimiter(base_delay=(2.0, 5.0), max_retries=2),
)
results = await crawler.arun_many(urls=urls, config=config_for(port), dispatcher=dispatcher)
for r in results:
print(port, r.url, r.status_code if r.success else r.error_message)
async def main():
browser = BrowserConfig(text_mode=True) # без картинок, шрифтов и медиа
async with AsyncWebCrawler(config=browser) as crawler:
parts = [URLS[i::len(PORTS)] for i in range(len(PORTS))]
await asyncio.gather(*(worker(crawler, p, part) for p, part in zip(PORTS, parts)))
asyncio.run(main())MemoryAdaptiveDispatcher с max_session_permit=2 держит открытыми не больше двух страниц на воркер, а RateLimiter добавляет случайную паузу 2–5 секунд между запросами к одному домену. page_timeout задаётся в миллисекундах, по умолчанию 60000: через резидентские адреса страницы грузятся медленнее, чем напрямую, так что 90 секунд — разумный запас. Время удержания IP в кабинете поставьте дольше, чем занимает часть списка одного воркера.
Как читать error_message в Crawl4AI: коды net::ERR и тайм-ауты
Crawl4AI не бросает исключение на неудачной странице: result.success равен False, а причина — в result.error_message, после «Failed on navigating ACS-GOTO». Самые частые причины через прокси:
- net::ERR_PROXY_CONNECTION_FAILED. Chromium не смог подключиться к прокси: неверный хост или порт в
server, либо исходящие соединения на этот порт заблокированы на вашей машине или в контейнере. - net::ERR_TUNNEL_CONNECTION_FAILED. Прокси доступен, но не открыл туннель к сайту. Проверьте, что на плане есть трафик и он не на паузе, что сайта нет в списке закрытых сайтов и что он работает на открытом порту, например 80, 443, 8080 или 8443.
- Timeout 60000ms exceeded. Страница не загрузилась за
page_timeout. Увеличьте его и оставьтеwait_until="domcontentloaded"(значение по умолчанию): ожиданиеnetworkidleна страницах с бесконечными фоновыми запросами часто заканчивается тайм-аутом. successравен True, ноstatus_code— 403 или 429. Сайт ответил, но отказывает.RateLimiterпо умолчанию реагирует на 429 и 503: удваивает паузу для этого домена и останавливается послеmax_retriesтаких ответов подряд. На 403 замедлитесь сами и проверьте правила сайта.
Экономия трафика в Crawl4AI: кэш, text_mode и robots.txt
Браузер загружает всё, что просит страница, а трафик считается в обе стороны. В версии 0.9.5 CrawlerRunConfig по умолчанию не читает кэш, так что каждый запуск загружает страницы заново. CacheMode.ENABLED читает и пишет локальный кэш, и повторный запуск берёт уже имеющиеся страницы с диска.
BrowserConfig(text_mode=True) блокирует картинки, шрифты и медиафайлы и выключает JavaScript. Трафика становится заметно меньше, но страницы, которые строят содержимое на JavaScript, вернутся пустыми: для них оставьте text_mode выключенным и используйте avoid_css=True. Обратите внимание: exclude_all_images и exclude_external_images только чистят результат, а картинки всё равно загружаются.
check_robots_txt=True заставляет краулер читать robots.txt и пропускать запрещённые страницы с сообщением «Access denied by robots.txt». Это простой способ держать сбор в рамках правил сайта и наших правил использования.
Если прокси не работает
Вопросы и ответы
Для какой версии написана инструкция?
Для версии Crawl4AI 0.9.5. В ней прокси передают через CrawlerRunConfig(proxy_config=…). Старый параметр proxy в BrowserConfig ещё работает, но печатает предупреждение об устаревании и будет убран.
Можно ли взять прокси из переменной окружения?
Да. ProxyConfig.from_env() читает переменную PROXIES со списком через запятую в формате хост:порт:логин:пароль, например gw.prokso.com:823:ЛОГИН:ПАРОЛЬ. Так пароль не попадает в код.
Что значит ошибка 407?
Прокси не принял логин или пароль. Скопируйте их из генератора в кабинете ещё раз, без пробелов в начале и в конце, и проверьте, остался ли трафик на плане.
Можно ли дать arun_many список прокси вместо деления адресов?
proxy_config принимает и список ProxyConfig, но это упорядоченный список для попыток по очереди, а не распределение адресов между IP. Чтобы привязать часть списка к одному IP, запускайте отдельный arun_many() со своим портом, как в примере.
Почему с text_mode получается пустой markdown?
text_mode выключает JavaScript в браузере. Если сайт рисует содержимое скриптами, конвертировать нечего. Для таких сайтов выключите text_mode и экономьте трафик кэшем и avoid_css.