← Zurück zum Blog

Aussortierung schlechter Proxys im Parser-Pool: Fehlerkennzahlen und Rotation mit Python

Wir analysieren, welche Fehlerkennzahlen auf eine Degradation des Proxys im Parser-Pool hinweisen und wie man ein automatisches System zur Ablehnung und Rotation von IPs aufbaut.

📅19. Oktober 2026

Wenn der Parser von Wildberries oder Ozon plötzlich leere Seiten, Timeouts und 403-Fehler zurückgibt, liegt das Problem nicht immer an der Plattform selbst. Häufig sind einige IP-Adressen im Proxy-Pool bereits „abgelaufen“: Sie wurden gesperrt, verlangsamt oder unter CAPTCHA gesetzt. Wir analysieren, anhand welcher Metriken man funktionierende Proxys von toten unterscheiden kann und wie man den Ausschluss automatisiert, ohne manuelle Kontrolle.

Warum der Proxy-Pool im Laufe der Zeit degradiert

Jeder Proxy-Pool – selbst wenn er von einem zuverlässigen Anbieter gekauft wurde – verliert im Laufe der Zeit einen Teil der funktionierenden Adressen. Die Gründe sind vielfältig: Die Anti-Fraud-Systeme von Wildberries, Ozon und Avito sammeln Reputationsmarken auf IPs, einige Adressen landen in schwarzen Listen nach massenhaften Anfragen anderer Kunden des Anbieters (wenn die Proxys shared sind), Rechenzentrumsbereiche werden in großen Mengen nach Subnetzen gesperrt, und Residential IPs verschwinden manchmal einfach aus dem Pool, weil der tatsächliche Benutzer das Gerät abgeschaltet hat.

Wenn der Pool nicht gereinigt wird, steigt der Anteil der „toten“ Proxys nichtlinear: Zuerst 5%, nach einer Woche aktiven Scraping – 20-30%. Der Parser beginnt, Ressourcen für Wiederholungsversuche über nicht funktionierende IPs auszugeben, die durchschnittliche Zeit zum Abrufen einer Seite steigt, und in den Logs sammeln sich Fehler, die echte Probleme maskieren (z.B. Änderungen im Layout der Website). Ohne ein Ausschlusssystem halten Sie entweder den Pool aufgebläht „für den Notfall“ oder erhalten regelmäßig Ausfälle beim Datensammeln.

Die Aufgabe besteht nicht nur darin, den Fehler festzustellen, sondern ihn zu klassifizieren: vorübergehende Serverüberlastung, Sperre einer bestimmten IP, regionale Blockierung oder ein Problem auf der Seite des Parsers (falsche Header, abgelaufene Cookies). Je nach Art des Fehlers hängt es davon ab, ob die Proxy dauerhaft aus dem Pool ausgeschlossen, vorübergehend in Quarantäne gesetzt oder einfach die Anfrage wiederholt werden muss.

Wichtige Fehlermetriken für den Ausschluss

Um einen vorübergehenden Ausfall von einem wirklich toten Proxy zu unterscheiden, müssen mehrere Metriken für jede IP gesammelt werden, anstatt sich auf einen einzelnen HTTP-Status zu verlassen. Hier ist eine grundlegende Sammlung, die bei jeder Anfrage protokolliert werden sollte:

Metrik Was signalisiert es Aktion
HTTP 403 / 429 Sperre oder Rate-Limit auf der IP Quarantäne 30-60 Minuten, bei Wiederholung – Ausschluss
Timeout der Verbindung Proxy überlastet oder tot 3 Timeouts hintereinander – Ausschluss aus dem Pool
CAPTCHA in der Antwort IP steht unter Verdacht des Anti-Bots Anfragerate senken oder IP wechseln
Antwortzeit > 5 Sek. Geschwindigkeitsdegradation auf der Proxy-Seite Priorität im Pool senken
Antwortgröße unter dem Durchschnitt Es wurde ein Platzhalter/blockierende Seite zurückgegeben Zusätzliche Überprüfung des Inhalts vor der Annahme
Erfolgsquote (Success Rate) Integrierte Qualitätsbewertung der IP Unter 70% bei 50 Anfragen – Ausschluss

Es ist wichtig, die Fehlercodes der Website nicht mit Netzwerkfehlern zu verwechseln. Zum Beispiel ist 404 kein Problem des Proxys, sondern ein nicht vorhandenes Produkt auf Wildberries. Wenn jedoch dieselbe IP regelmäßig 403 erhält, während andere IPs 200 erhalten, ist das ein eindeutiges Zeichen für eine gezielte Sperre dieser Adresse.

Scoring-Algorithmus für Proxys

Anstelle von binär „funktionierend / nicht funktionierend“ ist es bequemer, für jede IP einen Score von 0 bis 100 zu berechnen, der bei Fehlern allmählich sinkt und sich bei erfolgreichen Anfragen wieder erholt. Dies ermöglicht es, Proxys nicht nach einem zufälligen Ausfall auszuschließen (der Server des Marktplatzes könnte einfach für eine Sekunde hängen geblieben sein), sondern schnell die IPs zu entfernen, die systematisch Müll zurückgeben.

Die Logik ist einfach: Eine erfolgreiche Anfrage mit dem Code 200 und gültigem Inhalt fügt +2 zum Score hinzu (aber nicht über 100). Timeout – minus 15. Code 403/429 – minus 25. CAPTCHA in der Antwort – minus 20. Wenn der Score unter einen bestimmten Schwellenwert (z.B. 30) fällt, geht der Proxy für eine feste Zeit in Quarantäne, und wenn der Score nach der Rückkehr aus der Quarantäne erneut unter 10 fällt – wird die IP endgültig aus dem Pool entfernt und zur Analyse protokolliert.

Dieser Ansatz ähnelt dem Reputationssystem in Anti-Detect-Browsern wie Dolphin Anty oder AdsPower, wo Konten „Gesundheit“ basierend auf der Aktivität haben. Dieselbe Mechanik funktioniert auch hervorragend für IP-Adressen im Scraping.

Code: ProxyPool mit automatischem Ausschluss in Python

Im Folgenden finden Sie das funktionierende Gerüst einer Klasse zur Verwaltung des Proxy-Pools unter Berücksichtigung der Fehlermetriken. Diese kann an jeden Parser auf requests, httpx oder Scrapy angeschlossen werden, indem die Logik zum Abrufen von Proxys durch den Aufruf pool.get_proxy() ersetzt wird.

import time
import random
from dataclasses import dataclass, field
from typing import Optional

@dataclass
class ProxyStats:
    address: str
    score: int = 100
    quarantine_until: float = 0.0
    total_requests: int = 0
    total_success: int = 0
    consecutive_timeouts: int = 0
    is_dead: bool = False

    @property
    def success_rate(self) -> float:
        if self.total_requests == 0:
            return 1.0
        return self.total_success / self.total_requests


class ProxyPool:
    def __init__(self, proxies: list[str],
                 min_score: int = 30,
                 dead_score: int = 10,
                 quarantine_seconds: int = 1800):
        self.stats = {p: ProxyStats(address=p) for p in proxies}
        self.min_score = min_score
        self.dead_score = dead_score
        self.quarantine_seconds = quarantine_seconds

    def _is_available(self, stats: ProxyStats) -> bool:
        if stats.is_dead:
            return False
        if stats.quarantine_until > time.time():
            return False
        return True

    def get_proxy(self) -> Optional[str]:
        available = [s for s in self.stats.values() if self._is_available(s)]
        if not available:
            return None
        # sortieren nach Score, einen zufälligen aus den Top-30% nehmen, um nicht einen IP zu überlasten
        available.sort(key=lambda s: s.score, reverse=True)
        top_pool = available[:max(1, len(available) // 3)]
        return random.choice(top_pool).address

    def report_success(self, proxy: str):
        s = self.stats[proxy]
        s.total_requests += 1
        s.total_success += 1
        s.consecutive_timeouts = 0
        s.score = min(100, s.score + 2)

    def report_timeout(self, proxy: str):
        s = self.stats[proxy]
        s.total_requests += 1
        s.consecutive_timeouts += 1
        s.score -= 15
        if s.consecutive_timeouts >= 3:
            self._quarantine(s)
        self._check_dead(s)

    def report_blocked(self, proxy: str, captcha: bool = False):
        s = self.stats[proxy]
        s.total_requests += 1
        s.score -= 20 if captcha else 25
        self._quarantine(s)
        self._check_dead(s)

    def _quarantine(self, s: ProxyStats):
        if s.score < self.min_score:
            s.quarantine_until = time.time() + self.quarantine_seconds

    def _check_dead(self, s: ProxyStats):
        if s.score <= self.dead_score:
            s.is_dead = True

    def stats_report(self) -> list[dict]:
        return [
            {
                "proxy": s.address,
                "score": s.score,
                "success_rate": round(s.success_rate, 2),
                "dead": s.is_dead,
            }
            for s in self.stats.values()
        ]

In einem echten Parser werden die Aufrufe report_success, report_timeout und report_blocked direkt in den Antworthandler nach jeder HTTP-Anfrage eingefügt. Beispiel für die Integration mit requests:

import requests

def fetch(url: str, pool: ProxyPool):
    proxy = pool.get_proxy()
    if not proxy:
        raise RuntimeError("Es sind keine verfügbaren Proxys im Pool")

    proxies = {"http": proxy, "https": proxy}
    try:
        resp = requests.get(url, proxies=proxies, timeout=8)
    except requests.exceptions.Timeout:
        pool.report_timeout(proxy)
        return None

    if resp.status_code in (403, 429):
        pool.report_blocked(proxy)
        return None

    if "captcha" in resp.text.lower():
        pool.report_blocked(proxy, captcha=True)
        return None

    pool.report_success(proxy)
    return resp

Dieser Ansatz reduziert die Belastung durch manuelle Überwachung: Sie stellen die Schwellenwerte einmal ein, und der Pool „heilt“ sich selbst, indem er tote Adressen ausschließt und die, die vorübergehend hängen geblieben sind, aus der Quarantäne zurückholt.

Schwellenwerte für IP-Sperren

Universelle Zahlen existieren nicht – die Schwellenwerte hängen von der Plattform und der Aggressivität ihres Anti-Bots ab. Aber es gibt Richtwerte, die in der Praxis beim Scraping von Wildberries, Ozon und Avito gut funktionieren:

  • Erfolgsquote unter 70% bei einer Stichprobe von 30-50 Anfragen – Grund zur Löschung der IP, auch wenn der aktuelle Score noch nicht kritisch ist.
  • 3 Timeouts hintereinander – bedeutet fast immer, dass der Proxy physisch nicht verfügbar oder überlastet ist, es macht keinen Sinn, ihn im aktiven Pool zu halten.
  • CAPTCHA häufiger als 1 Mal alle 20 Anfragen – die IP steht bereits unter Verdacht beim Anti-Bot, es ist besser, die Anfragerate zu senken oder die Adresse zu wechseln.
  • Durchschnittliche Antwortzeit über 2x der Median des Pools – Signal für Degradation, nicht kritisch, aber ein Grund, die Priorität bei der Auswahl zu senken.

Eine Quarantäne von 30-60 Minuten ist normalerweise ausreichend für Rechenzentrums- und Residential-Proxys, damit der Anti-Bot die vorübergehende verdächtige Aktivität „vergisst“. Bei mobilen Proxys ist die Situation anders: Dort ändert sich die IP beim Wechsel des Mobilfunkmastes, daher kann die Quarantäne kürzer sein – 10-15 Minuten, da dies nach der Rotation physisch bereits eine andere Adresse ist.

Healthcheck und Rotation im Hintergrund

Neben dem reaktiven Ausschluss (basierend auf den Fehlern im Haupt-Parsing-Stream) ist es nützlich, einen Hintergrund-Healthcheck durchzuführen – einen separaten Prozess, der alle paar Minuten die Proxys mit leichten Anfragen an eine neutrale URL (z.B. httpbin.org/ip) abfragt und die Poolstatistik aktualisiert, bevor der Proxy in eine echte Anfrage an Wildberries oder Ozon gelangt.

import threading

def healthcheck_loop(pool: ProxyPool, interval: int = 300):
    while True:
        for proxy in list(pool.stats.keys()):
            try:
                r = requests.get(
                    "https://httpbin.org/ip",
                    proxies={"http": proxy, "https": proxy},
                    timeout=5
                )
                if r.status_code == 200:
                    pool.report_success(proxy)
                else:
                    pool.report_blocked(proxy)
            except requests.exceptions.RequestException:
                pool.report_timeout(proxy)
        time.sleep(interval)

threading.Thread(target=healthcheck_loop, args=(pool,), daemon=True).start()

Dieser Hintergrundprozess ist besonders wichtig, wenn der Pool groß ist (Hunderte von IPs) und das Scraping nicht kontinuierlich, sondern in Chargen erfolgt – ohne Healthcheck haben einige Proxys einfach die Möglichkeit, zwischen den Starts „abzulaufen“, und die ersten Minuten des Scraping werden für den Live-Ausschluss aufgewendet, anstatt sofort mit überprüften Adressen zu arbeiten.

Welchen Proxy-Typ für das Scraping von Marktplätzen wählen

Die Wahl des Proxy-Typs beeinflusst direkt, wie oft der Ausschluss durchgeführt werden muss und wie aggressiv die Schwellenwerte sein werden. Für stabiles Scraping von Wildberries und Ozon, wo der Anti-Bot Verhaltensmuster und die Reputation des Subnetzes analysiert, zeigen sich Residential Proxys am besten – ihre IPs gehören echten Anbietern von Internetdiensten, und der Anti-Bot blockiert sie deutlich seltener in großen Mengen nach Subnetz.

Für einfachere und weniger geschützte Quellen (z.B. das Sammeln öffentlicher Daten von Avito oder die Preisüberwachung auf einfachen Schaufenstern) sind oft Rechenzentrums-Proxys ausreichend – sie sind schneller und günstiger, was bei großen Anfragevolumina entscheidend ist, aber sie werden auch etwas häufiger gesperrt, daher sollten die Ausschlussschwellen für sie strenger gesetzt werden.

Proxy-Typ Ausschlussgeschwindigkeit Wann verwenden
Rechenzentrum Hoch, Subnetze werden in großen Mengen gesperrt Einfache Schaufenster, große Volumen, niedriger Schutz
Residential Mittel, IPs werden gezielt gesperrt Wildberries, Ozon, Websites mit Anti-Bot
Mobile Niedrig, IP ändert sich automatisch durch den Anbieter Streng geschützte Quellen, hochfrequentes Scraping

In der Praxis verwenden viele Teams einen hybriden Pool: Der Großteil der Anfragen erfolgt über Residential IPs, und bei massiven Sperren werden mobile Proxys als „Notfall“-Reserve angeschlossen, da deren IP-Wechsel auf natürliche Weise durch die Rotation des Mobilfunknetzes erfolgt und kein manuelles Eingreifen erfordert.

Fazit

Ein Proxy-Pool ohne Ausschlusssystem degradiert unvermeidlich, und je länger er ohne Reinigung arbeitet, desto mehr Ressourcen verschwendet der Parser auf tote IPs. Das Scoring-Modell unter Berücksichtigung von HTTP-Codes, Timeouts, CAPTCHA und Erfolgsquote ermöglicht es, problematische Adressen automatisch zu identifizieren und den Pool ohne manuelle Kontrolle in einem funktionsfähigen Zustand zu halten. Der Code aus diesem Artikel kann an jeden Stack angepasst werden – requests, httpx, Scrapy oder einen eigenen asynchronen Parser.

Wenn Sie gerade einen Pool für das Scraping von Marktplätzen aufbauen und die Sperrfrequenz von Anfang an senken möchten, empfehlen wir, sich Residential Proxys anzusehen – sie bieten eine deutlich höhere Erfolgsquote auf geschützten Plattformen wie Wildberries und Ozon im Vergleich zu normalen Rechenzentrumsadressen.