Налаштування проксі в Crawl4AI

Проксі в Crawl4AI: ProxyConfig з логіном і паролем у CrawlerRunConfig, країна в логіні, порт 823 для окремих сторінок і фіксований IP для сесії.

Оновлено · Редакція Prokso

Дані для підключення
Хост
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 (sticky-сесія) до 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.