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:
import requests
proxies = {
"http": "http://USER:PASS@gate.quantumproxies.io:PORT",
"https": "http://USER:PASS@gate.quantumproxies.io:PORT",
}
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łujeMissingSchema. Gołe ciągiip:portdział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 kluczahttps. Nazwa klucza określa docelowy protokół; wartość określa, jak dotrzeć do proxy. Proxy akceptują zwykły HTTP i tunelują TLS przez żądanie CONNECT. Pisaniehttps://tam jest klasyczną przyczynąSSLError: UNEXPECTED_EOF_WHILE_READING. - Klucze mogą celować w konkretne hosty. Klucz taki jak
https://api.example.comkieruje 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. 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:
import requests
session = requests.Session()
session.proxies = {
"http": "http://USER:PASS@gate.quantumproxies.io:PORT",
"https": "http://USER:PASS@gate.quantumproxies.io:PORT",
}
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.

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 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:
import requests
proxies = {
"http": "http://USER:PASS@gate.quantumproxies.io:PORT",
"https": "http://USER:PASS@gate.quantumproxies.io:PORT",
}
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 zwiększa przepustowość, a system middleware Scrapy 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:
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@gate.quantumproxies.io:PORT",
"https": "http://USER:PASS@gate.quantumproxies.io:PORT",
}
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 na tej samej bramie, więc zmiana protokołów to zamiana schematu, a nie nowy zakup:
proxies = {
"http": "socks5h://USER:PASS@gate.quantumproxies.io:PORT",
"https": "socks5h://USER:PASS@gate.quantumproxies.io:PORT",
}

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 kluczahttps. Ustaw schemat wartości nahttp://. - 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.proxiesi spróbujtrust_env = False.
Aby głębiej przejść przez ślady stosu i ich przyczyny źródłowe, zobacz debugowanie ProxyError, SSLError i ConnectTimeout w Requests.
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