# Przewodnik po proxy w Python Requests: składnia, uwierzytelnianie, rotacja, ponowne próby

Słownik proxies to trzy linie kodu, a jednak błędy proxy w Requests wypełniają dekadę na Stack Overflow. Oto pełna konfiguracja — składnia, uwierzytelnianie, zmienne środowiskowe, rotacja, ponowne próby i SOCKS5 — z oznaczonymi ostrymi krawędziami.

Python Requests nadal jest domyślnym klientem HTTP do scrapingu i automatyzacji, a wskazanie go na proxy to zadanie na trzy linie: przekaż słownik proxies, a każde żądanie wychodzi z IP proxy zamiast z twojego. Jednak 'python requests proxy not working' pozostaje jednym z najczęściej wyszukiwanych tematów od ponad dekady — oryginalne pytanie na Stack Overflow dotyczące słownika proxies pochodzi z 2011 roku, jego najlepsza odpowiedź ma ponad 480 głosów, a wciąż była edytowana w styczniu 2026 roku. Składnia ma ostre krawędzie: brakujący schemat wywołuje wyjątek, zły schemat wewnątrz klucza https powoduje błędy SSL, a zmienne środowiskowe cicho nadpisują kod. Ten przewodnik po proxy w Python Requests obejmuje wszystko: składnię, uwierzytelnianie, zmienne środowiskowe, rotację, ponowne próby, SOCKS5 i błędy, które faktycznie napotkasz.

## Słownik proxies: składnia proxy w Python Requests

Argument `proxies` mapuje protokół na URL proxy. Dwa klucze obejmują normalny scraping — jeden dla zwykłych celów HTTP, drugi dla celów HTTPS — i oba zazwyczaj wskazują na to samo proxy:

```python
import requests

proxies = {
    "http": "http://USER:PASS@residentialpremium.quantumproxies.io:8080",
    "https": "http://USER:PASS@residentialpremium.quantumproxies.io:8080",
}

r = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=(5, 30))
print(r.json())  # {'origin': '<proxy exit IP>'}
```

Trzy zasady zapobiegają 90% błędów konfiguracji:

- **Schemat jest obowiązkowy.** Od wersji Requests 2.0.0 URL proxy bez `http://` wywołuje `MissingSchema`. Gołe ciągi `ip:port` działały w wersji 1.x i przestały działać wszędzie, gdy pojawiła się wersja 2.0.
- **Użyj `http://` wewnątrz klucza `https`.** Nazwa klucza określa docelowy protokół; wartość określa, jak dotrzeć do proxy. Proxy akceptują zwykły HTTP i tunelują TLS przez żądanie CONNECT. Pisanie `https://` tam jest klasyczną przyczyną `SSLError: UNEXPECTED_EOF_WHILE_READING`.
- **Klucze mogą celować w konkretne hosty.** Klucz taki jak `https://api.example.com` kieruje tylko ten host przez dane proxy — przydatne do wysyłania jednej trudnej domeny przez IP rezydencyjne, podczas gdy reszta idzie bezpośrednio.

## Uwierzytelnianie proxy: nazwa użytkownika i hasło

Uwierzytelnione proxy używają uwierzytelniania HTTP Basic osadzonego w URL: `http://USER:PASS@host:port`. Jeśli hasło zawiera `@`, `:` lub `/`, najpierw zakoduj je w URL za pomocą `urllib.parse.quote(password, safe="")` — niezakodowane znaki specjalne dzielą URL w niewłaściwym miejscu i powodują błędy uwierzytelniania, które wyglądają jak martwe proxy. Odpowiedź `407 Proxy Authentication Required` oznacza, że samo proxy cię odrzuciło: błędne dane uwierzytelniające lub plan z białą listą IP wywołany z niezarejestrowanego adresu. Oba przypadki są omówione w [naszym przewodniku po rozwiązywaniu problemów z 407](https://quantumproxies.io/blog/fix-407-proxy-authentication-required). Do czegoś więcej niż jednorazowy skrypt, dołącz proxy do `Session` — uzyskasz pooling połączeń, trwałość ciasteczek i jedno miejsce do konfiguracji wszystkiego:

```python
import requests

session = requests.Session()
session.proxies = {
    "http": "http://USER:PASS@residentialpremium.quantumproxies.io:8080",
    "https": "http://USER:PASS@residentialpremium.quantumproxies.io:8080",
}
session.headers.update({"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"})

r = session.get("https://httpbin.org/ip", timeout=(5, 30))
print(r.status_code, r.json())
```

## Zmienne środowiskowe i trust_env

Requests również odczytuje ustawienia proxy ze środowiska — te same zmienne, które respektuje curl i większość narzędzi Unix: `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY` i `NO_PROXY` (lista hostów do wykluczenia, np. `localhost,127.0.0.1,.internal`). To najczystszy sposób na proxy dla biblioteki zewnętrznej, która używa Requests pod maską, bez dotykania jej kodu. Priorytet jest taki: jawne wygrywa z ukrytym: argument `proxies=` w wywołaniu wygrywa, potem `session.proxies`, a potem środowisko. Warto znać dwa powiązane narzędzia: `session.trust_env = False` wyłącza całe wyszukiwanie środowiskowe — rozwiązanie, gdy zmienna proxy korporacyjnego przejmuje twojego scrapera — a `urllib.request.getproxies()` zwraca ustawienia proxy na poziomie systemu operacyjnego (w tym konfigurację systemu macOS i Windows) dokładnie w formie słownika, jakiego oczekuje Requests.

![Ten sam dwukluczowy słownik proxies wysyła trzy iteracje pętli przez tunel CONNECT rotującej bramy, a httpbin.org/ip za każdym razem zgłasza inne źródło: IP wyjściowe A, B i C. Karta: słownik wybiera trasę, tunel przenosi TLS do celu, a brama dostarcza nowe IP wyjściowe przy każdym wywołaniu.](https://res.cloudinary.com/dmqliab0t/image/upload/f_auto,q_auto,w_1200/v1785335141/blog/generated/qp-b9-001-diag1.png)
*Słownik wybiera trasę, brama dostarcza wyjściowy IP. Przy rotacji per żądanie te same dwie linie konfiguracji dają nowy IP przy każdym wywołaniu.*

## Rotacja: jedna brama bije listę proxy

Tradycyjny przepis na rotację — załaduj listę IP, `random.choice()` na żądanie, usuń martwe — to mechanizm, którego nie musisz już budować. Obracająca się brama robi to po stronie serwera: konfigurujesz jeden punkt końcowy, a dostawca przypisuje świeży wyjściowy IP z puli przy każdym żądaniu. Przez [obracające się proxy rezydencyjne](https://quantumproxies.io/rotating-proxies) ta pula to ponad 90 milionów IP gospodarstw domowych w ponad 200 krajach, więc tysiąc żądań wygląda jak tysiąc różnych odwiedzających bez ani jednej linii logiki rotacji:

```python
import requests

proxies = {
    "http": "http://USER:PASS@residentialpremium.quantumproxies.io:8080",
    "https": "http://USER:PASS@residentialpremium.quantumproxies.io:8080",
}

for _ in range(3):
    r = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=(5, 30))
    print(r.json()["origin"])  # a different exit IP on each iteration
```

Gdy przepływ obejmuje kilka żądań — logowanie, dodanie do koszyka, realizacja zakupu — rotacja per żądanie przerywa sesję. Sesje lepkie to rozwiązanie: parametr sesji w nazwie użytkownika proxy przypina jeden wyjściowy IP na określony czas, a potem rotuje. Ten sam punkt końcowy, jedna zmiana ciągu. Jeśli skalujesz się poza proste pętle, [asynchroniczny Python z httpx lub aiohttp](https://quantumproxies.io/blog/python-async-scraping-httpx-aiohttp-proxies) zwiększa przepustowość, a [system middleware Scrapy](https://quantumproxies.io/blog/scrapy-rotating-proxy-middleware) daje ci rotację, ponowne próby i obsługę banów jako konfigurację frameworka.

## Ponowne próby i limity czasu, które przetrwają złe wyjścia

Nawet premium pule serwują czasem wolne lub umierające wyjścia, więc kod produkcyjny potrzebuje dwóch zabezpieczeń: limitu czasu na każde żądanie (Requests domyślnie czeka w nieskończoność) i automatycznych ponownych prób z backoffem. Limit czasu przyjmuje krotkę `(connect, read)` — szybkie niepowodzenie na nieosiągalnych proxy, pozwala na wolniejsze odczyty stron. Ponowne próby montują się na warstwie transportowej przez urllib3:

```python
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

retry = Retry(
    total=4,
    backoff_factor=1,  # exponential backoff between attempts
    status_forcelist=[429, 500, 502, 503, 504],
    allowed_methods=["GET", "HEAD"],
)

session = requests.Session()
session.mount("http://", HTTPAdapter(max_retries=retry))
session.mount("https://", HTTPAdapter(max_retries=retry))
session.proxies = {
    "http": "http://USER:PASS@residentialpremium.quantumproxies.io:8080",
    "https": "http://USER:PASS@residentialpremium.quantumproxies.io:8080",
}

r = session.get("https://httpbin.org/ip", timeout=(5, 30))
```

Z obracającą się bramą ta kombinacja jest cicho potężna: każda ponowna próba przechodzi automatycznie przez inny wyjściowy IP, więc jeden niestabilny adres nigdy nie może spowodować niepowodzenia żądania cztery razy z rzędu.

## SOCKS5 proxy z Requests

Wsparcie dla SOCKS to dodatek: zainstaluj je za pomocą `pip install requests[socks]`. Następnie składnia słownika jest identyczna — zmienia się tylko schemat. Preferuj `socks5h://` nad `socks5://`: `h` przenosi rozwiązywanie DNS na proxy, co zapobiega wyciekom DNS z twojej rzeczywistej sieci i rozwiązuje geo-fencowane nazwy hostów z lokalizacji wyjścia. Każdy plan QuantumProxies udostępnia zarówno HTTP, jak i [SOCKS5 proxy](https://quantumproxies.io/socks5-proxies) na tej samej bramie, więc zmiana protokołów to zamiana schematu, a nie nowy zakup:

```python
proxies = {
    "http": "socks5h://USER:PASS@residentialpremium.quantumproxies.io:1080",
    "https": "socks5h://USER:PASS@residentialpremium.quantumproxies.io:1080",
}
```

![Pięć błędów proxy w Python Requests i ich skutki: brak schematu zgłasza MissingSchema, https:// w kluczu https daje SSLError, niezakodowane hasło kończy się 407, SOCKS wymaga dodatku requestssocks, a brak timeoutu oznacza czekanie w nieskończoność. Karta: trzy zasady zapobiegają 90% błędów konfiguracji.](https://res.cloudinary.com/dmqliab0t/image/upload/f_auto,q_auto,w_1200/v1785335141/blog/generated/qp-b9-001-diag2.png)
*Pięć błędów powoduje większość niepowodzeń: brakujący schemat, https:// w kluczu https, niezakodowane hasła, brakujące dodatki SOCKS i brak limitu czasu.*

## Najczęstsze błędy proxy w Python Requests, zdekodowane

- **MissingSchema** — URL proxy nie zawiera `http://`. Obowiązkowe od wersji Requests 2.0.0.
- **ProxyError: Cannot connect to proxy** — błędny host lub port, albo martwe proxy. Zweryfikuj punkt końcowy za pomocą curl, zanim obwinisz swój kod.
- **SSLError / UNEXPECTED_EOF_WHILE_READING** — zwykle `https://` wewnątrz klucza `https`. Ustaw schemat wartości na `http://`.
- **407 Proxy Authentication Required** — złe dane uwierzytelniające, niezakodowane znaki specjalne w haśle lub niebiałolistowany źródłowy IP.
- **ConnectTimeout / ReadTimeout** — wolne wyjście lub wolny cel. Ustaw `timeout=(5, 30)` i pozwól ponownym próbom rotować do świeżego IP.
- **Proxy działa w curl, nie działa w Pythonie** — zmienna środowiskowa nadpisuje twój słownik. Wydrukuj `session.proxies` i spróbuj `trust_env = False`.

Aby głębiej przejść przez ślady stosu i ich przyczyny źródłowe, zobacz [debugowanie ProxyError, SSLError i ConnectTimeout w Requests](https://quantumproxies.io/blog/python-requests-proxyerror-fix).

## Często zadawane pytania

### Jak używać proxy z Python Requests?

Przekaż słownik `proxies` z kluczami `http` i `https` do dowolnej metody żądania: `requests.get(url, proxies={...})`. Każda wartość to pełny URL proxy łącznie ze schematem, a dane uwierzytelniające są osadzone jako `http://user:pass@host:port`. Dołącz ten sam słownik do `Session`, aby automatycznie zastosować go do każdego żądania.

### Dlaczego moje proxy w Python Requests nie działa?

Sprawdź cztery zwykłe podejrzane w kolejności: brakujący schemat `http://` w URL proxy, `https://` użyte wewnątrz klucza `https`, znaki specjalne w haśle, które nie zostały zakodowane w URL, i zmienne środowiskowe nadpisujące twój kod. Przetestuj te same dane uwierzytelniające za pomocą curl — jeśli curl się powiedzie, problem leży w twoim słowniku.

### Czy Python Requests obsługuje proxy SOCKS5?

Tak, po zainstalowaniu dodatkowej zależności za pomocą `pip install requests[socks]`. Użyj schematu `socks5h://` w swoim słowniku proxies, aby rozwiązywanie DNS odbywało się po stronie proxy — zwykły schemat `socks5://` rozwiązuje nazwy hostów lokalnie, co wycieka zapytania DNS i może zepsuć scraping geo-celowany.

### Jak ustawić proxy za pomocą zmiennych środowiskowych?

Eksportuj `HTTP_PROXY` i `HTTPS_PROXY` z pełnym URL proxy, opcjonalnie `NO_PROXY` dla hostów do wykluczenia. Requests automatycznie je przechwytuje, co również proxyzuje biblioteki zewnętrzne zbudowane na Requests. Aby twój kod całkowicie ignorował środowisko, ustaw `session.trust_env = False`.

To cały zestaw narzędzi: słownik z dwoma kluczami, dane uwierzytelniające w URL, ponowne próby zamontowane raz i rotacja obsługiwana przez bramę zamiast twojego kodu. Jedyna rzecz, której żadna składnia nie naprawi, to jakość IP — idealnie skonfigurowane proxy centrum danych nadal jest blokowane tam, gdzie wyjście rezydencyjne przechodzi bez problemu. Połącz czysty kod z czystymi IP, a Requests obsłuży zaskakująco duże obciążenia.

[Zdobądź proxy rezydencyjne, które działają za pierwszym razem](https://quantumproxies.io/residential-proxies)
