Proxy w aiohttp: HTTP, HTTPS i SOCKS5

Proxy w aiohttp dla Pythona: parametr proxy w żądaniu, dane logowania w adresie URL, SOCKS5 przez aiohttp-socks i wybór portu dla żądań równoległych.

Zaktualizowano · Redakcja Prokso

Dane do połączenia
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ół.

W skrócie
  • Host gw.prokso.com, porty 823 (HTTP), 824 (SOCKS5), 10000–20000 (sesje ze stałym IP, 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 aiohttp. 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 przez całą sesję – maksymalnie 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.

Blok „Dostęp” na stronie planu: host, porty, login i hasło do linii proxy
Blok „Dostęp” na stronie planu: host, porty, login i hasło do linii proxy

Krok 2. Zainstaluj bibliotekę

pip install aiohttp. Dla SOCKS5 potrzebujesz jeszcze pip install aiohttp-socks.

Krok 3. Przekaż proxy do żądania

aiohttp przyjmuje proxy HTTP w parametrze proxy każdego żądania. Login i hasło wpisz bezpośrednio w adres URL.

import asyncio
import aiohttp

PROXY = "http://USERNAME:PASSWORD@gw.prokso.com:823"


async def main():
    async with aiohttp.ClientSession() as session:
        async with session.get("https://api.ipify.org?format=json", proxy=PROXY) as r:
            print(await r.json())


asyncio.run(main())
Przykład uruchomienia: w wyniku widać IP proxy, a nie Twoje. Na porcie 823 każde uruchomienie daje nowy adres
Przykład uruchomienia: w wyniku widać IP proxy, a nie Twoje. Na porcie 823 każde uruchomienie daje nowy adres

Krok 4. SOCKS5 przez aiohttp-socks

Sam aiohttp nie obsługuje SOCKS. Utwórz ProxyConnector z pakietu aiohttp-socks i przekaż go do sesji – wtedy każde żądanie w tej sesji przejdzie przez SOCKS5.

import asyncio
import aiohttp
from aiohttp_socks import ProxyConnector


async def main():
    connector = ProxyConnector.from_url("socks5://USERNAME:PASSWORD@gw.prokso.com:824")
    async with aiohttp.ClientSession(connector=connector) as session:
        async with session.get("https://api.ipify.org?format=json") as r:
            print(await r.json())


asyncio.run(main())

Krok 5. Wiele żądań naraz

Do równoległego zbierania danych używaj portu 823 (lub 824 dla SOCKS5): każde żądanie dostaje nowy adres. Aby zachować jeden IP dla serii żądań, użyj portu ze stałym IP z zakresu 10000–20000.

Krok 6. Sprawdź wynik

Uruchom przykład: skrypt wysyła żądanie do 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. Strona „Mój IP” w przeglądarce tu nie pomoże: przeglądarka łączy się bezpośrednio.

Ograniczenie współbieżności i limity czasu

aiohttp bez trudu uruchamia tysiące żądań naraz i właśnie to najczęściej kończy się błędami 429 i przekroczeniem limitu czasu. Ogranicz liczbę jednoczesnych żądań semaforem i ustaw ogólny limit czasu dla sesji:

import asyncio
import aiohttp

PROXY = "http://USERNAME:PASSWORD@gw.prokso.com:823"
URLS = ["https://prokso.com/ip"] * 20


async def fetch(session, sem, url):
    async with sem:                                   # no more than 10 requests at once
        async with session.get(url, proxy=PROXY) as r:
            return r.status, await r.text()


async def main():
    sem = asyncio.Semaphore(10)
    timeout = aiohttp.ClientTimeout(total=30)
    async with aiohttp.ClientSession(timeout=timeout) as session:
        results = await asyncio.gather(*(fetch(session, sem, u) for u in URLS), return_exceptions=True)
    print(results)


asyncio.run(main())

return_exceptions=True sprawia, że jedno nieudane żądanie nie anuluje pozostałych: błędy wracają na liście wyników i możesz ponowić je osobno.

Co oznaczają błędy

  • ClientHttpProxyError, status 407. Proxy nie przyjęło loginu lub hasła albo skończył się transfer.
  • ClientProxyConnectionError. Nie udało się połączyć z proxy: sprawdź host i port.
  • asyncio.TimeoutError. Żądanie nie zmieściło się w limicie czasu. Ponów je albo zwiększ limit.
  • ServerDisconnectedError. Połączenie zostało zerwane. Zwykle pomaga ponowienie i mniejsza współbieżność.

Kody 403 i 429 zwraca strona: co z nimi zrobić, opisujemy na stronie błędu 429.

Jeden IP dla grupy żądań

Każde żądanie na porcie 823 wychodzi z nowego IP. Jeśli kilka żądań musi przyjść z jednego adresu - logowanie, a potem strony konta - użyj dla nich portu ze stałym IP i osobnej sesji: wtedy pliki cookie i IP pozostaną spójne.

HTTP, HTTPS czy SOCKS5: jaki adres proxy rozumie aiohttp

Schemat na początku adresu proxy opisuje połączenie z proxy, a nie ze stroną. Dlatego proxy="http://…" działa zarówno dla stron http://, jak i https://: dla HTTPS aiohttp otwiera tunel metodą CONNECT, a ruch do strony pozostaje zaszyfrowany. Osobny adres https:// dla proxy nie jest potrzebny.

Adres proxyJak podłączyćPort Prokso
http://LOGIN:HASLO@gw.prokso.com:823wbudowane w aiohttp, parametr proxy=823 - nowe IP przy każdym żądaniu
http://LOGIN:HASLO@gw.prokso.com:10000wbudowane w aiohttp, parametr proxy=10000-20000 - stałe IP
socks5://LOGIN:HASLO@gw.prokso.com:824aiohttp-socks, ProxyConnector824 - nowe IP przy każdym połączeniu
socks5://LOGIN:HASLO@gw.prokso.com:10000aiohttp-socks, ProxyConnector10000-20000 - stałe IP

Adres socks5:// w parametrze proxy= nie zadziała: według dokumentacji aiohttp sam aiohttp obsługuje tylko proxy HTTP. Połączenie z proxy przez https:// (TLS do samego proxy) jest w aiohttp obsługiwane w ograniczonym zakresie, więc z Prokso używaj http://.

aiohttp-socks szczegółowo: DNS po stronie proxy, stałe IP i kilka proxy

Zamiast adresu w jednym ciągu aiohttp-socks przyjmuje też parametry osobno - wygodnie, gdy hasło bierzesz ze zmiennej środowiskowej:

import asyncio
import os

import aiohttp
from aiohttp_socks import ProxyConnector, ProxyType


async def main():
    connector = ProxyConnector(
        proxy_type=ProxyType.SOCKS5,
        host="gw.prokso.com",
        port=10000,                      # sticky IP; 824 - a new IP for every connection
        username="LOGIN__cr.de",         # country in the username
        password=os.environ["PROKSO_PASSWORD"],
        rdns=True,                       # site names are resolved on the proxy side
    )
    async with aiohttp.ClientSession(connector=connector) as session:
        async with session.get("https://api.ipify.org?format=json") as r:
            print(await r.json())


asyncio.run(main())

Dla SOCKS5 rdns=True jest domyślne: nazwę strony rozwiązuje proxy, a nie Twój komputer. Dzięki temu Twój serwer DNS nie widzi, jakie strony otwiera skrypt - więcej o wycieku DNS.

Konektor należy do sesji: wszystkie żądania jednej sesji idą przez jedno proxy. Jeśli potrzebujesz naraz kilku IP lub krajów, utwórz osobną sesję dla każdej linii proxy:

import asyncio

import aiohttp
from aiohttp_socks import ProxyConnector

LINES = [
    "socks5://LOGIN__cr.de:PASSWORD@gw.prokso.com:10001",
    "socks5://LOGIN__cr.pl:PASSWORD@gw.prokso.com:10002",
]


async def fetch_ip(line):
    async with aiohttp.ClientSession(connector=ProxyConnector.from_url(line)) as session:
        async with session.get("https://api.ipify.org?format=json") as r:
            return await r.json()


async def main():
    print(await asyncio.gather(*(fetch_ip(line) for line in LINES)))


asyncio.run(main())

Sprawdź, czy adresy naprawdę się różnią: skrypt wypisuje IP każdej sesji. Jak aiohttp ponownie używa połączeń i dlaczego kilka żądań z rzędu może wyjść z jednego adresu nawet na porcie 824, wyjaśnia artykuł o keep-alive.

Błędy aiohttp-socks i co sprawdzić

  • ProxyConnectionError - skrypt nie dotarł do gw.prokso.com: sprawdź port i czy Twoja sieć go nie blokuje.
  • ProxyError - proxy odmówiło: zły login lub hasło, SOCKS5 na porcie HTTP 823 albo w planie skończył się transfer.
  • ProxyTimeoutError - proxy nie odpowiedziało na czas: powtórz żądanie lub zwiększ limit czasu.
from aiohttp_socks import ProxyConnectionError, ProxyError, ProxyTimeoutError

try:
    async with session.get(url) as r:
        body = await r.text()
except ProxyConnectionError:
    ...  # gw.prokso.com:PORT is unreachable: check the port and your network
except ProxyError as e:
    ...  # the proxy refused: username, password, protocol/port or traffic balance
except ProxyTimeoutError:
    ...  # no answer in time: retry or raise the timeout

Błędy samego aiohttp przy proxy HTTP (na przykład status 407) opisuje sekcja wyżej o błędach oraz strona 407 Proxy Authentication Required.

Jeśli proxy nie działa

Pytania i odpowiedzi (FAQ)

Czy aiohttp odczytuje proxy ze zmiennych środowiskowych?

Tylko jeśli utworzysz sesję z trust_env=True – wtedy odczytuje HTTP_PROXY i HTTPS_PROXY. Jawne przekazanie proxy, jak w przykładzie, jest bardziej niezawodne.

Ile jednoczesnych żądań mogę uruchomić?

Plan pozwala na maksymalnie 1000 jednoczesnych połączeń. Ogranicz współbieżność w kodzie (na przykład semaforem), aby zmieścić się w limicie i nie przeciążać docelowej strony.

Czy mogę ustawić proxy raz dla całej sesji?

W aktualnych wersjach aiohttp parametr proxy przyjmuje także sama sesja. W starszych wersjach trzeba go przekazywać w każdym żądaniu.

Jak zakodować znaki specjalne w haśle?

Przepuść login i hasło przez urllib.parse.quote(..., safe="") albo przekaż je osobno przez proxy_auth=aiohttp.BasicAuth(...).

Jak użyć proxy HTTPS w aiohttp?

Podaj adres ze schematem http:// w parametrze proxy: dla stron https aiohttp sam otwiera tunel CONNECT, a ruch do strony pozostaje zaszyfrowany. Adres proxy z https:// (TLS do proxy) jest w aiohttp obsługiwany w ograniczonym zakresie.

Czy aiohttp obsługuje SOCKS5 bez dodatkowych bibliotek?

Nie, sam aiohttp działa tylko z proxy HTTP. Dla SOCKS5 zainstaluj aiohttp-socks i przekaż sesji ProxyConnector.

Którego portu używać z aiohttp-socks?

824 to SOCKS5 z nowym IP przy każdym połączeniu, 10000-20000 dają stałe IP od 1 do 120 minut; stałe porty przyjmują zarówno HTTP, jak i SOCKS5. Port 823 to tylko HTTP i nie działa z SOCKS5.