Zurück zum Blog

Warum Proxy im Browser funktioniert, aber nicht im Code: Vollständige Problemanalyse

Proxy funktioniert im Browser, aber das Skript wirft Fehler? Wir analysieren typische Ursachen und bieten fertige Lösungen für Python, Node.js und cURL.

📅11. Dezember 2025
```html

Warum der Proxy im Browser funktioniert, aber nicht im Code: Eine vollständige Analyse

Klassische Situation: Sie konfigurieren einen Proxy im Browser, öffnen eine Website – alles funktioniert. Sie starten ein Skript mit demselben Proxy – Verbindungsfehler, Timeout oder eine Sperre. Wir erklären, warum das passiert und wie Sie es beheben können.

Worin sich eine Browseranfrage von einer Code-Anfrage unterscheidet

Wenn Sie eine Website über einen Proxy im Browser öffnen, passiert viel mehr als nur eine einfache HTTP-Anfrage. Der Browser führt automatisch folgende Schritte durch:

  • Sendet einen vollständigen Satz von Headern (User-Agent, Accept, Accept-Language, Accept-Encoding)
  • Führt einen TLS-Handshake mit einem korrekten Satz von Chiffren durch
  • Verarbeitet Weiterleitungen (Redirects) und Cookies
  • Führt JavaScript aus und lädt abhängige Ressourcen
  • Cacht DNS-Antworten und Zertifikate

Eine minimale Anfrage aus dem Code sieht für den Server völlig anders aus – eher wie ein Roboter als wie ein Mensch. Selbst wenn der Proxy korrekt funktioniert, blockiert die Zielseite möglicherweise speziell Ihr Skript.

Probleme mit der Proxy-Authentifizierung

Die häufigste Ursache ist die falsche Übergabe von Benutzername und Passwort. Der Browser zeigt ein Eingabefenster für die Anmeldedaten an, im Code muss dies jedoch explizit erfolgen.

Falsches URL-Format

Ein häufiger Fehler ist das Weglassen des Schemas oder die falsche Maskierung von Sonderzeichen:

# Falsch
proxy = "user:pass@proxy.example.com:8080"

# Richtig
proxy = "http://user:pass@proxy.example.com:8080"

# Wenn das Passwort Sonderzeichen enthält (@, :, /)
from urllib.parse import quote
password = quote("p@ss:word/123", safe="")
proxy = f"http://user:{password}@proxy.example.com:8080"

Authentifizierung per IP vs. Benutzername/Passwort

Einige Proxy-Anbieter verwenden eine Whitelist basierend auf der IP-Adresse. Der Browser auf Ihrem Computer funktioniert, weil Ihre IP zur Whitelist hinzugefügt wurde. Das Skript auf einem Server funktioniert jedoch nicht, da der Server eine andere IP-Adresse hat.

Überprüfen Sie im Dashboard des Anbieters, welche Authentifizierungsmethode verwendet wird und welche IPs zur Whitelist hinzugefügt sind.

Inkompatibilität der Protokolle HTTP/HTTPS/SOCKS

Der Browser erkennt den Proxypunkt oft automatisch. Im Code muss der Typ explizit angegeben werden, und ein Fehler im Protokoll führt zu einer stillschweigenden Ablehnung.

Proxypunkt Schema in der URL Besonderheiten
HTTP Proxy http:// Funktioniert für HTTP und HTTPS via CONNECT
HTTPS Proxy https:// Verschlüsselte Verbindung zum Proxy
SOCKS4 socks4:// Ohne Authentifizierung, nur IPv4
SOCKS5 socks5:// Mit Authentifizierung, UDP, IPv6
SOCKS5h socks5h:// DNS-Auflösung über den Proxy

Es ist entscheidend: Wenn Sie einen SOCKS5-Proxy haben, aber http:// angeben, wird die Verbindung nicht hergestellt. Die Bibliothek versucht, über das HTTP-Protokoll mit dem SOCKS-Server zu kommunizieren.

Fehlende Header und Fingerprinting

Selbst wenn der Proxy korrekt funktioniert, kann die Zielseite die Anfrage aufgrund verdächtiger Header blockieren. Vergleichen Sie:

Anfrage aus dem Browser

GET /api/data HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36...
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1

Standardanfrage mit requests

GET /api/data HTTP/1.1
Host: example.com
User-Agent: python-requests/2.28.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive

Der Unterschied ist offensichtlich. Eine Seite mit Anti-Bot-Schutz erkennt sofort, dass die Anfrage nicht von einem Browser stammt.

Minimaler Satz von Headern zur Tarnung

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.9",
    "Accept-Encoding": "gzip, deflate, br",
    "Connection": "keep-alive",
    "Upgrade-Insecure-Requests": "1",
    "Sec-Fetch-Dest": "document",
    "Sec-Fetch-Mode": "navigate",
    "Sec-Fetch-Site": "none",
    "Sec-Fetch-User": "?1",
    "Cache-Control": "max-age=0"
}

SSL-Zertifikate und Verifizierung

Der Browser verfügt über einen integrierten Speicher für Stammzertifikate und kann verschiedene SSL-Konfigurationen verarbeiten. Im Code können Probleme auftreten:

SSL-Fehler: CERTIFICATE_VERIFY_FAILED

Einige Proxys verwenden eigene Zertifikate zur Verkehrsinspektion. Ihr Browser hat dieses Zertifikat möglicherweise als vertrauenswürdig eingestuft, Ihr Skript jedoch nicht.

# Temporäre Lösung zum Debuggen (NICHT für die Produktion!)
import requests
response = requests.get(url, proxies=proxies, verify=False)

# Korrekte Lösung – Pfad zum Zertifikat angeben
response = requests.get(url, proxies=proxies, verify="/path/to/proxy-ca.crt")

Wichtig: Das Deaktivieren der SSL-Verifizierung (verify=False) macht die Verbindung anfällig für MITM-Angriffe. Verwenden Sie dies nur zum Debuggen in einer sicheren Umgebung.

TLS Fingerprint

Fortgeschrittene Anti-Bot-Systeme analysieren den TLS-Fingerabdruck – die Reihenfolge und den Satz von Chiffren bei der Verbindungsherstellung. Python requests verwendet einen Standardsatz, der sich von dem des Browsers unterscheidet.

Um dies zu umgehen, verwenden Sie Bibliotheken mit einem benutzerdefinierten TLS-Fingerabdruck:

# Installation: pip install curl-cffi
from curl_cffi import requests

response = requests.get(
    url,
    proxies={"https": proxy},
    impersonate="chrome120"  # Imitiert den TLS-Fingerabdruck von Chrome 120
)

DNS-Lecks und Auflösung

Ein weiteres nicht offensichtliches Problem ist die DNS-Auflösung. Bei der Verwendung eines HTTP-Proxys kann die DNS-Anfrage direkt von Ihrer Maschine gesendet werden und den Proxy umgehen.

Wie sich dies auf die Funktion auswirkt

  • Die Website sieht den tatsächlichen DNS-Resolver und nicht den Proxy
  • Die Geolokalisierung wird falsch bestimmt
  • Einige Websites blockieren die Nichtübereinstimmung zwischen IP und DNS-Region

Lösung für SOCKS5

Verwenden Sie das Schema socks5h:// anstelle von socks5:// – der Buchstabe "h" bedeutet, dass die DNS-Auflösung auf der Proxy-Seite erfolgt:

# DNS wird lokal aufgelöst (Leck!)
proxy = "socks5://user:pass@proxy.example.com:1080"

# DNS wird über den Proxy aufgelöst (korrekt)
proxy = "socks5h://user:pass@proxy.example.com:1080"

Funktionierende Beispiele für Python, Node.js und cURL

Python mit requests

import requests
from urllib.parse import quote

# Proxy-Daten
proxy_host = "proxy.example.com"
proxy_port = "8080"
proxy_user = "username"
proxy_pass = quote("p@ssword!", safe="")  # Sonderzeichen maskieren

# Proxy-URL erstellen
proxy_url = f"http://{proxy_user}:{proxy_pass}@{proxy_host}:{proxy_port}"

proxies = {
    "http": proxy_url,
    "https": proxy_url
}

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.9",
    "Accept-Encoding": "gzip, deflate, br",
}

try:
    response = requests.get(
        "https://httpbin.org/ip",
        proxies=proxies,
        headers=headers,
        timeout=30
    )
    print(f"Status: {response.status_code}")
    print(f"IP: {response.json()}")
except requests.exceptions.ProxyError as e:
    print(f"Proxy-Fehler: {e}")
except requests.exceptions.ConnectTimeout:
    print("Timeout beim Verbindungsaufbau zum Proxy")

Python mit aiohttp (Asynchron)

import aiohttp
import asyncio

async def fetch_with_proxy():
    proxy_url = "http://user:pass@proxy.example.com:8080"
    
    async with aiohttp.ClientSession() as session:
        async with session.get(
            "https://httpbin.org/ip",
            proxy=proxy_url,
            headers={"User-Agent": "Mozilla/5.0..."}
        ) as response:
            return await response.json()

result = asyncio.run(fetch_with_proxy())
print(result)

Node.js mit axios

const axios = require('axios');
const HttpsProxyAgent = require('https-proxy-agent');

const proxyUrl = 'http://user:pass@proxy.example.com:8080';
const agent = new HttpsProxyAgent(proxyUrl);

axios.get('https://httpbin.org/ip', {
    httpsAgent: agent,
    headers: {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36...'
    }
})
.then(response => console.log(response.data))
.catch(error => console.error('Error:', error.message));

Node.js mit node-fetch und SOCKS

const fetch = require('node-fetch');
const { SocksProxyAgent } = require('socks-proxy-agent');

const agent = new SocksProxyAgent('socks5://user:pass@proxy.example.com:1080');

fetch('https://httpbin.org/ip', { agent })
    .then(res => res.json())
    .then(data => console.log(data));

cURL

# HTTP Proxy
curl -x "http://user:pass@proxy.example.com:8080" \
     -H "User-Agent: Mozilla/5.0..." \
     https://httpbin.org/ip

# SOCKS5 Proxy mit DNS über Proxy
curl --socks5-hostname "proxy.example.com:1080" \
     --proxy-user "user:pass" \
     https://httpbin.org/ip

# Debugging – den gesamten Verbindungsprozess anzeigen
curl -v -x "http://user:pass@proxy.example.com:8080" \
     https://httpbin.org/ip

Diagnose-Checkliste

Wenn der Proxy im Code nicht funktioniert, überprüfen Sie die folgenden Punkte der Reihe nach:

  1. Proxy-URL-Format – Ist das Schema (http://, socks5://) vorhanden?
  2. Sonderzeichen im Passwort – Sind diese URL-kodiert?
  3. Proxypunkt – Stimmt das angegebene Protokoll mit dem tatsächlichen überein?
  4. Authentifizierung – Erfolgt die Authentifizierung per IP oder per Login? Ist die IP des Servers in der Whitelist?
  5. Header – Wurden Browser-Header wie User-Agent hinzugefügt?
  6. SSL – Gibt es Zertifikatsfehler?
  7. DNS – Wird socks5h:// verwendet, um die Auflösung über den Proxy zu erzwingen?
  8. Timeouts – Ist genügend Zeit für den Verbindungsaufbau eingeräumt (besonders bei Residenz-Proxys)?

Fazit

Der Unterschied zwischen Browser und Code liegt in den Details: Header, Protokolle, SSL, DNS. Der Browser verbirgt diese Komplexität, während im Code jeder Aspekt explizit konfiguriert werden muss. Beginnen Sie mit der Überprüfung des URL-Formats und der Authentifizierung und fügen Sie dann die Browser-Header hinzu – dies löst 90 % der Probleme.

Für Web-Scraping- und Automatisierungsaufgaben, bei denen Stabilität und eine geringe Sperrquote wichtig sind, eignen sich Residenz-Proxys hervorragend – mehr darüber erfahren Sie auf proxycove.com.

```