ProxyError w requests: Unable to connect to proxy
Biblioteka requests nie przeszła przez proxy: albo nie połączyła się z nim, albo proxy odmówiło otwarcia tunelu do strony. Co dokładnie się stało, widać z długiej treści błędu.
Zaktualizowano · Redakcja Prokso
- ProxyError oznacza, że requests nie przeszedł przez proxy: nie połączył się lub nie dostał tunelu
- Prawdziwa przyczyna jest w nawiasie po Caused by, a słowo po 407 lub 503 nazywa ją dokładnie
- Ustaw linię proxy ze schematem http:// dla obu kluczy słownika i sprawdź zmienne środowiskowe
Co oznacza błąd
Komunikat wygląda tak: HTTPSConnectionPool(host='example.com', port=443): Max retries exceeded with url: / (Caused by ProxyError('Unable to connect to proxy', ...)). Najważniejsze jest w nawiasie po Caused by. Biblioteka urllib3, na której działa requests, opakowuje prawdziwą przyczynę w ProxyError, a requests zgłasza ją jako requests.exceptions.ProxyError.
Słowa Max retries exceeded nie oznaczają, że prób było wiele. Według dokumentacji requests domyślnie nie ponawia nieudanych połączeń, więc ten tekst pojawia się już po pierwszej próbie. W starej gałęzi urllib3 1.26 zamiast Unable to connect to proxy pisało się Cannot connect to proxy. Sens jest ten sam.
W środku zwykle jest jeden z dwóch wariantów. NewConnectionError z Connection refused albo ConnectTimeoutError oznacza, że z proxy nie udało się nawet połączyć. OSError('Tunnel connection failed: 407 NO_USER') oznacza, że połączenie z proxy jest, ale na żądanie CONNECT odpowiedziało ono kodem innym niż 200. Po kodzie stoi tekst odpowiedzi, a w Prokso nazywa on przyczynę: NO_USER, TRAFFIC_EXHAUSTED, THREADS_EXHAUSTED, NO_RAY lub NO_HOST_CONNECTION.
Przyczyny
- Błędny host lub port. Connection refused albo timeout połączenia: w linii nie ma gw.prokso.com lub port jest spoza 823, 824 i 10000–20000.
- Login lub hasło nie zostały przyjęte. Tunnel connection failed: 407 NO_USER oznacza błąd w loginie lub haśle. Jeśli logujesz się przez IP, bieżącego adresu nie ma na liście dozwolonych.
- Wyczerpany limit planu. 407 TRAFFIC_EXHAUSTED: skończył się transfer. 407 THREADS_EXHAUSTED: otwarto ponad 1000 jednoczesnych połączeń na plan.
- Brak adresu pod geo lub strona niedostępna. 503 NO_RAY: pod wybrany kraj, miasto lub ASN nie ma teraz wolnego IP. 502 NO_HOST_CONNECTION: proxy nie połączyło się ze stroną.
- Znaki specjalne w haśle bez kodowania. Znaki @, : lub # w loginie albo haśle psują parsowanie linii i do proxy trafiają nie te dane.
Jak to naprawić
- Skopiuj linię proxy z panelu klienta jeszcze raz i ustaw ją dla obu kluczy:
proxies={'http': 'http://LOGIN:HASŁO@gw.prokso.com:823', 'https': 'http://LOGIN:HASŁO@gw.prokso.com:823'}. Schemat samego proxy to tu http://, nawet gdy strona działa na https://. - Jeśli hasło zawiera znaki specjalne, zakoduj login i hasło przez
urllib.parse.quote(HASŁO, safe=''), zanim wstawisz je do linii. - Przeczytaj słowo po kodzie w Tunnel connection failed. Przy NO_USER sprawdź login i listę IP, przy TRAFFIC_EXHAUSTED doładuj transfer, przy THREADS_EXHAUSTED zmniejsz liczbę wątków, przy NO_RAY poszerz geo.
- Sprawdź zmienne środowiskowe HTTP_PROXY, HTTPS_PROXY i ALL_PROXY. Requests je odczytuje, a dokumentacja ostrzega, że mogą nadpisać
session.proxies. Pewniej jest przekazywaćproxies=do każdego żądania. - Ustaw
timeout=(10, 30)i dodaj ponawianie z przerwą dla 502 i 503: na porcie 823 ponowienie pójdzie już przez inny IP. Pełny przykład jest w instrukcji Python requests, a ogólną kolejność szukania przyczyny opisuje strona rozwiązywania problemów.
Jak sprawdzić, czy działa
Wykonaj requests.get('https://prokso.com/ip', proxies=proxies, timeout=30).json(). Jeśli w odpowiedzi jest IP i kraj proxy, a nie Twoje, połączenie działa. Tę samą linię możesz sprawdzić bez kodu w sprawdzarce proxy: jeśli tam wszystko jest w porządku, przyczyny szukaj w kodzie lub zmiennych środowiskowych.
Diagnoza w 2 minuty
Najpierw wklej linię do sprawdzania proxy. Jeśli tam proxy działa, przyczyna leży w programie lub jego ustawieniach. Jeśli nie - sprawdź linię z terminala:
curl -v -x "http://LOGIN:HASŁO@gw.prokso.com:823" https://api.ipify.org
- Wiersz
< HTTP/1.1 407zaraz poCONNECToznacza, że odpowiada proxy. Nazwa po kodzie, na przykładNO_USER, wskazuje przyczynę. - Proxy odpowiedziało na
CONNECTkodem 200, a potem przyszedł inny kod - proxy działa, tę odpowiedź dała strona. - Brak odpowiedzi, tylko przekroczony czas - połączenie nie dotarło do proxy: sprawdź host, port i sieć.
Instrukcje, w których pojawia się ten błąd
Pytania i odpowiedzi (FAQ)
Dlaczego dla strony http 407 przychodzi jako odpowiedź, a nie wyjątek?
Dla adresów http:// requests nie otwiera tunelu, tylko wysyła żądanie do proxy bezpośrednio. Dlatego 407 wraca jako zwykły response.status_code. Tunel CONNECT jest potrzebny tylko dla https://, i tam odmowa staje się wyjątkiem ProxyError. Co oznacza sam kod, wyjaśnia strona <a href="/pl/errors/407-proxy-authentication-required">407 Proxy Authentication Required</a>.
Co zrobić, jeśli w środku jest ConnectTimeoutError?
Proxy nie odpowiedziało w czasie przeznaczonym na połączenie. Sprawdź host i port, sieć i zaporę, a potem stronę <a href="/pl/errors/proxy-timeout">timeout proxy</a>.
Dlaczego strona widzi mój adres, choć proxy jest ustawione?
Najczęściej w słowniku jest tylko klucz 'http', a strona działa na https://. Klucz odpowiada schematowi strony, więc żądania do https:// idą bezpośrednio. Ustaw oba klucze.
Czy wystarczy przechwytywać tylko ProxyError?
ProxyError jest podklasą requests.exceptions.ConnectionError. Błędy proxy SOCKS requests zgłasza jako ConnectionError, więc jeśli pracujesz z oboma protokołami, przechwytuj ConnectionError.
Inne błędy proxy
Rezydencjalne $1.59, mobilne $2.50, serwerowe $0.65 za 1 GB
Rejestracja w minutę, dostęp od razu po płatności.