- Host
- gw.prokso.com
- Port
- 823 HTTP · 824 SOCKS5 — nowy IP przy każdym żądaniu · 10000–20000 stały IP na całą sesję, HTTP(S) i SOCKS5
- Login i hasło
- w panelu klienta, na stronie planu
Gotowe wiersze w potrzebnym formacie wygenerujesz w panelu klienta: wybierz kraj, typ IP i protokół.
- Host gw.prokso.com, porty 823 (HTTP), 824 (SOCKS5), 10000–20000 (stały IP na sesję, HTTP lub SOCKS5)
- Login i hasło znajdziesz w panelu klienta na stronie planu
- Sprawdzaj IP w odpowiedzi na samo żądanie wysłane przez proxy: strona „Mój IP” w przeglądarce nie testuje Twojego skryptu
Instrukcja krok po kroku, jak podłączyć proxy Prokso w Crawl4AI. Zajmie Ci to kilka minut.
Krok 1. Pobierz dane proxy z panelu klienta
Otwórz swój plan i skopiuj host gw.prokso.com, port, login i hasło. Port 823 to HTTP, a 824 to SOCKS5 (oba dają nowy IP przy każdym żądaniu); porty 10000–20000 utrzymują jeden IP (stały IP na sesję) do 120 minut i działają zarówno jako HTTP, jak i SOCKS5 (każdy port to osobny adres). Kraj ustawiasz w loginie: username__cr.ua.
Krok 2. Zainstaluj Crawl4AI
pip install -U crawl4ai, a potem crawl4ai-setup: to polecenie instaluje przeglądarkę, w której Crawl4AI otwiera strony. Instalację sprawdzisz poleceniem crawl4ai-doctor. Instrukcja dotyczy wersji 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="USERNAME",
password="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())Zapisz kod w pliku, na przykład crawl.py, i uruchom go poleceniem python crawl.py.
Krok 3. Przekaż proxy do CrawlerRunConfig
Utwórz ProxyConfig z adresem http://gw.prokso.com:823 i osobnymi polami username oraz password, a następnie przekaż go jako parametr proxy_config w CrawlerRunConfig. Tak zaleca oficjalna dokumentacja: proxy ustawia się dla każdego wywołania arun, a parametr proxy w BrowserConfig jest tam oznaczony jako wycofywany.
Krok 4. Login, hasło i kraj
Login i hasło weź z generatora w panelu klienta. Osobne pola username i password są wygodniejsze niż adres URL z hasłem w środku: znaków specjalnych nie trzeba kodować. Login ustala kraj: USERNAME__cr.de otwiera strony z niemieckich adresów. Dla przeglądarki używaj schematu http://: Chromium wysyła login i hasło tylko do proxy HTTP.
Krok 5. Wybierz port do zadania
Port 823 daje nowy IP przy każdym żądaniu, co pasuje do jednorazowego pobierania pojedynczych stron. Jeśli crawler przechodzi przez kilka stron jednego serwisu w ramach jednej sesji (logowanie, koszyk, kolejne strony wyników), użyj portu ze stałym IP z zakresu 10000-20000: serwis wiąże sesję z IP, a zmiana adresu w jej trakcie wygląda podejrzanie. Adres na porcie utrzymuje się od 1 do 120 minut; czas ustawiasz w panelu klienta.
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="USERNAME",
password="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())Zapisz kod w pliku, na przykład crawl.py, i uruchom go poleceniem python crawl.py.
Krok 6. Kilka sesji – każda na swoim porcie
Ponieważ proxy jest ustawiane w CrawlerRunConfig, dla każdej sesji możesz zbudować osobną konfigurację z własnym portem ze stałym IP. Przykład używa dwóch portów: żądania przez jeden port zwracają ten sam IP, a różne porty dają różne adresy.
Krok 7. Sprawdź wynik
Uruchom przykład: crawler otwiera https://api.ipify.org i wypisuje IP, który widzi strona. Powinien to być adres proxy, a nie Twój. Błąd 407 oznacza nieprawidłowy login lub hasło albo wyczerpany transfer w planie. Strona „Mój IP” w Twojej przeglądarce tu nie pomoże: skrypt uruchamia własną przeglądarkę, a Twoja łączy się bezpośrednio.
arun_many i port ze stałym IP dla każdego workera
arun_many() bierze całą listę adresów i otwiera strony równolegle przez dyspozytor. Proxy siedzi w CrawlerRunConfig, więc z jedną konfiguracją wszystkie strony idą przez to samo proxy: na porcie 823 każda dostaje nowy IP. Jeśli strony mają iść ze stałego zestawu adresów, podziel listę i daj każdej części własny port ze stałym IP.
import asyncio
import os
from crawl4ai import (AsyncWebCrawler, BrowserConfig, CacheMode, CrawlerRunConfig,
MemoryAdaptiveDispatcher, ProxyConfig, RateLimiter)
PASSWORD = os.environ["PROKSO_PASSWORD"] # hasło nie trafia do kodu
URLS = [f"https://example.de/catalog?page={n}" for n in range(1, 31)]
PORTS = [10001, 10002, 10003] # jeden port ze stałym IP = jeden IP na workera
def config_for(port):
return CrawlerRunConfig(
proxy_config=ProxyConfig(
server=f"http://gw.prokso.com:{port}",
username="USERNAME__cr.de",
password=PASSWORD,
),
cache_mode=CacheMode.ENABLED, # nie pobieraj ponownie tego, co jest w cache
page_timeout=90000, # milisekundy
)
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) # bez obrazków, czcionek i multimediów
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 z max_session_permit=2 trzyma otwarte najwyżej dwie strony na workera, a RateLimiter dodaje losową przerwę 2-5 sekund między żądaniami do jednej domeny. page_timeout podajesz w milisekundach, domyślnie 60000: przez adresy rezydencjalne strony ładują się wolniej niż bezpośrednio, więc 90 sekund to rozsądny zapas. Czas utrzymania IP w panelu ustaw dłuższy, niż trwa część listy jednego workera.
Jak czytać error_message w Crawl4AI: kody net::ERR i limity czasu
Crawl4AI nie zgłasza wyjątku przy nieudanej stronie: result.success ma wartość False, a przyczyna jest w result.error_message, po Failed on navigating ACS-GOTO. Najczęstsze przyczyny przez proxy:
- net::ERR_PROXY_CONNECTION_FAILED. Chromium nie połączył się z proxy: zły host lub port w
serveralbo połączenia wychodzące na ten port są zablokowane na twojej maszynie lub w kontenerze. - net::ERR_TUNNEL_CONNECTION_FAILED. Proxy jest osiągalne, ale nie otworzyło tunelu do strony. Sprawdź, czy plan ma transfer i nie jest wstrzymany, czy strony nie ma na liście zablokowanych stron i czy działa na otwartym porcie, takim jak 80, 443, 8080 lub 8443.
- Timeout 60000ms exceeded. Strona nie załadowała się w czasie
page_timeout. Zwiększ go i zostawwait_until="domcontentloaded"(wartość domyślna): czekanie nanetworkidlena stronach z niekończącymi się żądaniami w tle często kończy się przekroczeniem czasu. successma wartość True, alestatus_codeto 403 lub 429. Strona odpowiedziała, ale odmawia.RateLimiterdomyślnie reaguje na 429 i 503: podwaja przerwę dla tej domeny i zatrzymuje się pomax_retriestakich odpowiedziach z rzędu. Przy 403 zwolnij sam i sprawdź zasady strony.
Oszczędzanie transferu w Crawl4AI: cache, text_mode i robots.txt
Przeglądarka pobiera wszystko, o co prosi strona, a transfer liczy się w obie strony. W wersji 0.9.5 CrawlerRunConfig domyślnie nie czyta cache, więc każde uruchomienie pobiera strony od nowa. CacheMode.ENABLED czyta i zapisuje lokalny cache, a kolejne uruchomienie bierze posiadane już strony z dysku.
BrowserConfig(text_mode=True) blokuje obrazki, czcionki i pliki multimedialne oraz wyłącza JavaScript. Transferu jest wyraźnie mniej, ale strony budujące treść w JavaScripcie wrócą puste: dla nich zostaw text_mode wyłączony i użyj avoid_css=True. Uwaga: exclude_all_images i exclude_external_images tylko czyszczą wynik, a obrazki i tak są pobierane.
check_robots_txt=True sprawia, że crawler czyta robots.txt i pomija niedozwolone strony z komunikatem Access denied by robots.txt. To prosty sposób, by trzymać zbieranie w granicach zasad strony i naszych zasad korzystania.
Jeśli proxy nie działa
Pytania i odpowiedzi (FAQ)
Dla jakiej wersji jest ta instrukcja?
Dla Crawl4AI w wersji 0.9.5. W niej proxy przekazuje się przez CrawlerRunConfig(proxy_config=…). Stary parametr proxy w BrowserConfig nadal działa, ale wyświetla ostrzeżenie o wycofaniu i zostanie usunięty.
Czy mogę wczytać proxy ze zmiennej środowiskowej?
Tak. ProxyConfig.from_env() odczytuje zmienną PROXIES z listą rozdzieloną przecinkami w formacie host:port:username:password, na przykład gw.prokso.com:823:USERNAME:PASSWORD. Dzięki temu hasło nie trafia do kodu.
Co oznacza błąd 407?
Proxy odrzuciło login lub hasło. Skopiuj je ponownie z generatora w panelu klienta, bez spacji na początku i na końcu, i sprawdź, czy w planie został jeszcze transfer.
Czy mogę dać arun_many listę proxy zamiast dzielić adresy?
proxy_config przyjmuje też listę ProxyConfig, ale to uporządkowana lista do kolejnych prób, a nie podział adresów między IP. Żeby przypiąć część listy do jednego IP, uruchom osobne arun_many() z własnym portem, jak w przykładzie.
Dlaczego z text_mode dostaję pusty markdown?
text_mode wyłącza JavaScript w przeglądarce. Jeśli strona rysuje treść skryptami, nie ma czego konwertować. Dla takich stron wyłącz text_mode i oszczędzaj transfer dzięki cache i avoid_css.