← Zurück zum Blog

Python-Anfragen: ProxyError, SSLError WRONG_VERSION_NUMBER und 407 – praktische Lösungen zur Behebung

Detaillierte Analyse häufiger Fehler bei der Arbeit mit Proxys in Python Requests: ProxyError, SSLError WRONG_VERSION_NUMBER, 407 Proxy-Authentifizierung erforderlich. Funktionierende Codebeispiele für jede Situation.

📅11. November 2026

Wenn Sie Websites parsen oder Anfragen über Proxys in Python automatisieren, werden Sie früher oder später mit drei klassischen Fehlern konfrontiert: ProxyError, SSLError: WRONG_VERSION_NUMBER und HTTP 407 Proxy Authentication Required. In diesem Artikel werden wir die Ursache jedes einzelnen Fehlers untersuchen und funktionierenden Code zur Behebung bereitstellen.

Wie requests mit Proxys funktioniert: Grundsyntax

Die Bibliothek requests akzeptiert Proxys über ein Dictionary proxies, wobei die Schlüssel die Anfrage-Schemata (http und https) sind und die Werte die URL des Proxy-Servers mit optionaler Authentifizierung.

import requests

proxies = {
    "http": "http://user:password@proxy_host:port",
    "https": "http://user:password@proxy_host:port",
}

response = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=10)
print(response.json())

Beachten Sie: Selbst für HTTPS-Anfragen wird das Proxy-Schema normalerweise als http:// angegeben, da die meisten Proxy-Server den CONNECT-Tunnel über das HTTP-Protokoll akzeptieren und nicht in SSL einwickeln. Wenn Sie https:// für einen Proxy angeben, der dies nicht unterstützt, erhalten Sie genau SSLError, dessen Analyse weiter unten folgt.

Wenn Sie mit SOCKS5-Proxys arbeiten, benötigen Sie ein zusätzliches Paket:

pip install requests[socks]

# Und die Syntax für Proxys ändert sich:
proxies = {
    "http": "socks5://user:password@proxy_host:port",
    "https": "socks5://user:password@proxy_host:port",
}

ProxyError: Ursachen und Lösungen

requests.exceptions.ProxyError ist eine Wrapper-Exception für niedrigstufige Netzwerkfehler, die beim Versuch, eine Verbindung zu einem Proxy-Server herzustellen, auftreten. Am häufigsten treten vier Szenarien auf.

1. Proxy nicht verfügbar oder Adresse/Port falsch angegeben

requests.exceptions.ProxyError: HTTPSConnectionPool(host='example.com', port=443):
Max retries exceeded with url: / (Caused by ProxyError('Cannot connect to proxy.',
ConnectionResetError(104, 'Connection reset by peer')))

Überprüfen Sie, ob Host und Port korrekt eingegeben sind und ob der Proxy-Server tatsächlich läuft. Der schnellste Weg zur Diagnose ist, zu versuchen, sich über curl zu verbinden:

curl -x http://user:password@proxy_host:port https://httpbin.org/ip -v

2. Proxy hat Ihre Anfrage blockiert (IP- oder User-Agent-Sperre)

Rechenzentrums-Proxys werden häufig von Zielwebsites gesperrt, da ihre IP-Bereiche den Anti-Fraud-Systemen bekannt sind. Wenn der Fehler stabil auftritt, wenn Sie auf eine bestimmte Website zugreifen (z. B. Wildberries, Ozon oder soziale Netzwerke), und nicht auf allen Websites gleichzeitig, liegt das Problem nicht am Proxy selbst, sondern an dessen Reputation. In diesem Fall hilft der Wechsel zu residential Proxys — sie verwenden IPs echter Benutzer und werden seltener von Anti-Fraud-Systemen blockiert.

3. Limit der gleichzeitigen Verbindungen überschritten

Wenn Sie ein mehrstufiges Parsing durchführen und Hunderte von Verbindungen über denselben Proxy öffnen, kann der Server beginnen, überflüssige Verbindungen zurückzusetzen. Die Lösung besteht darin, einen Verbindungs-Pool über requests.adapters.HTTPAdapter mit einer Begrenzung von pool_maxsize und max_retries zu verwenden:

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

session = requests.Session()
retries = Retry(total=3, backoff_factor=1, status_forcelist=[502, 503, 504])
adapter = HTTPAdapter(max_retries=retries, pool_connections=20, pool_maxsize=20)

session.mount("http://", adapter)
session.mount("https://", adapter)

response = session.get("https://httpbin.org/ip", proxies=proxies, timeout=10)

4. Timeout auf der Seite des Proxy-Servers

Wenn der Proxy "hängt" länger als der festgelegte Timeout, sehen Sie ProxyError, eingewickelt in ReadTimeoutError. Erhöhen Sie den Timeout auf einen angemessenen Wert (normalerweise sind 15-30 Sekunden ausreichend) und fügen Sie eine separate Ausnahmebehandlung hinzu:

try:
    response = requests.get(url, proxies=proxies, timeout=20)
except requests.exceptions.ProxyError as e:
    print(f"Problem mit dem Proxy: {e}")
except requests.exceptions.Timeout:
    print("Der Proxy hat innerhalb der vorgegebenen Zeit nicht geantwortet")

SSLError WRONG_VERSION_NUMBER: Problemanalyse

Dieser Fehler ist auf den ersten Blick einer der unverständlichsten, hat aber in der Tat fast immer einen Grund.

requests.exceptions.SSLError: HTTPSConnectionPool(host='example.com', port=443):
Max retries exceeded with url: / (Caused by SSLError(SSLError(1, '[SSL:
WRONG_VERSION_NUMBER] falsche Versionsnummer (_ssl.c:1123)')))

WRONG_VERSION_NUMBER bedeutet, dass der Client versucht hat, ein SSL/TLS-Handshake durchzuführen, während der Server normalen HTTP-Verkehr (ohne Verschlüsselung) erwartet. Am häufigsten liegt der Grund in einer falsch angegebenen Proxy-Schema im Dictionary proxies.

Häufiger Fehler: Angabe von https:// anstelle von http:// in der Adresse des Proxy-Servers. Die meisten HTTP(S)-Proxys akzeptieren Verbindungen über normales HTTP, selbst wenn sie HTTPS-Verkehr über den CONNECT-Mechanismus proxieren.

# FALSCH — verursacht WRONG_VERSION_NUMBER
proxies = {
    "http": "https://user:password@proxy_host:port",
    "https": "https://user:password@proxy_host:port",
}

# RICHTIG
proxies = {
    "http": "http://user:password@proxy_host:port",
    "https": "http://user:password@proxy_host:port",
}

Ein zweiter häufiger Grund ist ein Port, der physisch kein TLS unterstützt. Wenn der Proxy-Anbieter beispielsweise Port 8080 nur für HTTP-Verkehr reserviert hat und Sie versuchen, eine TLS-Verbindung direkt (ohne CONNECT) herzustellen, wird der Server mit normalem Text anstelle eines TLS-Handshakes antworten, und die OpenSSL-Clientbibliothek wird genau diesen Fehler ausgeben. Überprüfen Sie in der Dokumentation Ihres Proxy-Anbieters, welche Ports und Protokolle (HTTP/HTTPS/SOCKS5) an jedem einzelnen Port verfügbar sind.

Eine dritte Möglichkeit ist, dass Sie socket oder externe Bibliotheken für eine direkte TCP-Verbindung mit dem Proxy verwenden, wobei Sie den Standardmechanismus von requests umgehen. In diesem Fall stellen Sie sicher, dass die TLS-Wicklung nur für die tatsächliche Zielwebsite und nicht für die Verbindung zum Proxy angewendet wird.

407 Proxy Authentication Required: Authentifizierung

Der Antwortcode 407 ist das Äquivalent zu 401, jedoch für Proxy-Server. Er bedeutet, dass der Server eine Authentifizierung verlangt, die Sie entweder nicht übermittelt haben oder in falschem Format übermittelt haben.

Methode 1: Benutzername und Passwort direkt in der URL

proxies = {
    "http": "http://login:password@proxy_host:port",
    "https": "http://login:password@proxy_host:port",
}

response = requests.get("https://httpbin.org/ip", proxies=proxies)

Diese Methode ist die einfachste, aber wenn im Benutzernamen oder Passwort Sonderzeichen enthalten sind (z. B. @, :, /), müssen sie über urllib.parse.quote maskiert werden:

from urllib.parse import quote

login = quote("user@domain")
password = quote("p@ssw:ord!")

proxy_url = f"http://{login}:{password}@proxy_host:port"
proxies = {"http": proxy_url, "https": proxy_url}

Methode 2: Proxy-Authorization-Header manuell

Wenn der Proxy-Anbieter ein nicht standardmäßiges Authentifizierungsschema verwendet oder Sie mehr Kontrolle benötigen, können Sie den Header manuell über Base64-Codierung zusammenstellen:

import base64
import requests

login = "user"
password = "password"
credentials = base64.b64encode(f"{login}:{password}".encode()).decode()

headers = {
    "Proxy-Authorization": f"Basic {credentials}"
}

proxies = {
    "http": "http://proxy_host:port",
    "https": "http://proxy_host:port",
}

response = requests.get(
    "https://httpbin.org/ip",
    proxies=proxies,
    headers=headers,
    timeout=10
)

Wichtig: Einige Proxy-Anbieter binden die Authentifizierung nicht an Benutzername/Passwort, sondern an eine bestimmte statische IP des Clients (Whitelist). Wenn Sie die IP ändern (z. B. über VPN oder dynamische IP des Anbieters), kann der 407-Fehler selbst bei korrekten Anmeldedaten auftreten — weil Ihre aktuelle externe IP nicht auf der Whitelist des Proxys steht. Die Lösung besteht darin, sich in das persönliche Konto des Anbieters einzuloggen und die Liste der erlaubten IPs zu aktualisieren oder auf Authentifizierung über Benutzername/Passwort anstelle von IP-Whitelist umzuschalten.

Retry-Logik und Ausnahmebehandlung

In der Praxis sind Proxy-Fehler selten einmalige Ereignisse — insbesondere beim massenhaften Parsen. Eine korrekte Code-Architektur sollte Wiederholungsversuche mit Verzögerung und Protokollierung jedes Fehlers separat vorsehen.

import time
import requests
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

def fetch_with_retry(url, proxies, max_retries=3, backoff=2):
    for attempt in range(1, max_retries + 1):
        try:
            response = requests.get(url, proxies=proxies, timeout=15)
            response.raise_for_status()
            return response
        except requests.exceptions.ProxyError as e:
            logger.warning(f"[Versuch {attempt}] ProxyError: {e}")
        except requests.exceptions.SSLError as e:
            logger.warning(f"[Versuch {attempt}] SSLError: {e}")
        except requests.exceptions.HTTPError as e:
            if response.status_code == 407:
                logger.error("407: Überprüfen Sie Benutzername/Passwort oder Whitelist-IP des Proxys")
                break
            logger.warning(f"[Versuch {attempt}] HTTPError: {e}")
        except requests.exceptions.Timeout:
            logger.warning(f"[Versuch {attempt}] Verbindungs-Timeout")

        time.sleep(backoff * attempt)

    raise RuntimeError(f"Fehler beim Abrufen von {url} nach {max_retries} Versuchen")

Dieser Ansatz spart Stunden der Fehlersuche: Anstatt dass das Skript beim ersten Netzwerkproblem abstürzt, erhalten Sie ein verständliches Protokoll mit dem spezifischen Fehler-Typ bei jedem Versuch.

Proxy-Rotation und Bekämpfung von Sperren

Während ProxyError und 407 häufig mit den Code-Einstellungen zusammenhängen, deuten massenhafte Sperren und stabile Verbindungsabbrüche bei bestimmten Domains fast immer auf ein Problem mit der Qualität des IP-Pools hin. Für Aufgaben wie das Parsen von Marktplätzen (Wildberries, Ozon, Avito) oder die Arbeit mit sozialen Netzwerken wird empfohlen, die IP bei jeder Anfrage oder über einen festgelegten Zeitraum zu rotieren.

import random

proxy_pool = [
    "http://user:[email protected]:8000",
    "http://user:[email protected]:8000",
    "http://user:[email protected]:8000",
]

def get_random_proxy():
    proxy = random.choice(proxy_pool)
    return {"http": proxy, "https": proxy}

response = requests.get(url, proxies=get_random_proxy(), timeout=15)

Für Produktionsparser ist es in der Regel bequemer, Proxys mit automatischer Rotation auf der Seite des Anbieters zu verwenden — dann müssen Sie die IP-Liste nicht selbst speichern, die Rotation erfolgt transparent über einen Endpunkt. In diesem Fall residential Proxys mit Rotation eignen sich besonders gut, um Anti-Bot-Schutz auf Websites mit strengen Erkennungssystemen zu umgehen, während Rechenzentrums-Proxys eine gute Wahl sind, wenn die Geschwindigkeit der Anfragen wichtig ist und die Zielwebsite nicht aggressiv Rechenzentrumsbereiche blockiert.

Proxy-Typ Geschwindigkeit Sperrrisiko Aufgaben
Rechenzentrums-Proxys Hoch Mittel-hoch Schnelles Parsen öffentlicher APIs
Residential Proxys Mittel Niedrig Parsing von Marktplätzen, sozialen Netzwerken
Mobile Proxys Mittel-niedrig Minimal Arbeiten mit strengen Anti-Bot-Systemen

Session, Timeouts und SSL-Überprüfung

Für langlebige Skripte (z. B. zyklische Parser) sollte requests.Session() anstelle von einzelnen Aufrufen requests.get() verwendet werden. Die Session wiederverwendet TCP-Verbindungen, was die Belastung des Proxy-Servers verringert und die Anzahl der ProxyErrors bei großen Anfragevolumina reduziert.

session = requests.Session()
session.proxies.update({
    "http": "http://user:password@proxy_host:port",
    "https": "http://user:password@proxy_host:port",
})

for url in urls_list:
    try:
        resp = session.get(url, timeout=15)
        print(resp.status_code, url)
    except requests.exceptions.RequestException as e:
        print(f"Fehler bei {url}: {e}")

Besonders erwähnenswert ist der Parameter verify. Wenn Sie mit einem Proxy arbeiten, der das SSL-Zertifikat selbst ersetzt (MITM-Proxy zur Fehlersuche oder einige Unternehmensproxies), kann requests über die Nichtübereinstimmung des Zertifikats meckern. Die vollständige Deaktivierung der Überprüfung (verify=False) sollte nur in einer Testumgebung erfolgen — in der Produktion birgt dies das Risiko von "Man-in-the-Middle"-Angriffen:

# Nur für lokale Fehlersuche!
response = requests.get(url, proxies=proxies, verify=False, timeout=15)

# Der richtige Weg — den Pfad zu einem vertrauenswürdigen Zertifikat des Proxys angeben
response = requests.get(url, proxies=proxies, verify="/path/to/proxy_cert.pem")

Fehlerdiagnose-Checkliste

Wenn das Skript mit einem Proxy-Fehler abstürzt, gehen Sie diese Liste von oben nach unten durch — in 90% der Fälle finden Sie die Ursache in den ersten drei Punkten.

  1. Überprüfen Sie das Schema im Dictionary proxies — es sollte fast immer http:// sein, selbst für HTTPS-Anfragen.
  2. Testen Sie den Proxy direkt über curl -x, um ein Problem auf der Code-Seite auszuschließen.
  3. Stellen Sie sicher, dass Benutzername und Passwort keine nicht maskierten Sonderzeichen in der URL enthalten.
  4. Überprüfen Sie, ob der Proxy an eine bestimmte IP (Whitelist) gebunden ist, anstelle von Authentifizierung über Benutzername/Passwort.
  5. Erhöhen Sie den timeout auf 15-30 Sekunden, bevor Sie den Proxy als nicht funktionsfähig betrachten.
  6. Wenn der Fehler nur auf einer bestimmten Website auftritt — das Problem liegt in der Reputation der IP und nicht im Code.
  7. Fügen Sie eine Retry-Logik mit exponentieller Verzögerung hinzu, anstatt nur einmalige Versuche zu unternehmen.
  8. Verwenden Sie bei massenhaften Parsen IP-Rotation und nicht einen statischen Proxy für alle Anfragen.

Fazit

Die meisten Proxy-Fehler in Python requests lassen sich auf drei Dinge zurückführen: ein falsches Schema in der Proxy-URL (http anstelle von https), fehlende oder falsche Authentifizierungsformate und die Qualität des IP-Pools selbst. ProxyError deutet normalerweise auf ein Verbindungsproblem oder eine IP-Sperre hin, SSLError WRONG_VERSION_NUMBER weist fast immer auf ein falsches Proxy-Schema hin, und 407 — auf ein Problem mit Benutzername/Passwort oder Whitelist.

Wenn Sie regelmäßig mit Sperren und 407-Fehlern beim Parsen von Marktplätzen oder sozialen Netzwerken konfrontiert sind, sollten Sie die Quelle des Proxys selbst überdenken und nicht nur den Code. Für stabiles Parsen mit einer niedrigen Blockierungsrate empfehlen wir, residential Proxys auszuprobieren — sie verwenden echte IP-Adressen und verursachen deutlich seltener ProxyErrors auf geschützten Websites. Wenn jedoch Geschwindigkeit und Anfragevolumen wichtiger sind als das Umgehen komplexer Anti-Bot-Systeme, sollten Sie sich die Rechenzentrums-Proxys ansehen — sie sind günstiger und schneller für einfache Parsing-Aufgaben.