Scarnox · Blog

Roterende proxies voor scraping: opzet en valkuilen

Een roterende proxy verandert het IP-adres waarvan je verkeer vertrekt, hetzij bij elk request, hetzij na een vast interval. Het is een van de meest gebruikte hulpmiddelen bij webscraping, en een van de vaakst verkeerd gebruikte. Te weinig roteren en één adres wordt snelheidsbeperkt. Te veel roteren en het verkeer ziet er helemaal niet uit als een bezoeker. Deze gids legt de twee rotatiemodellen uit, laat een werkende Python-opzet zien met retries voor dode proxies, en behandelt hoe een proxyveld past bij captchaoplossing.

Roteren versus vaste sessies

Een roterende proxydienst geeft adressen op twee manieren uit:

Een echte bezoeker houdt één adres voor een heel bezoek. Vaste sessies sluiten daar op aan, dus het zijn meestal de betere standaard wanneer een site cookies of sessies gebruikt. Gebruik rotatie per request voor stateless crawlen.

Een basis roterende pool in Python

Het onderstaande voorbeeld houdt een pool van proxy-URL's bij, roteert erdoorheen en schuift door naar de volgende wanneer er een faalt. Bewaar inloggegevens in omgevingsvariabelen, nooit in broncode.

import itertools
import os
import requests

# Proxy-URL's komen uit de omgeving, bijvoorbeeld:
# PROXY_POOL="http://user:pass@203.0.113.10:8080,http://user:pass@203.0.113.11:8080"
PROXIES = [p.strip() for p in os.environ.get("PROXY_POOL", "").split(",") if p.strip()]
rotation = itertools.cycle(PROXIES)

def fetch(url: str, max_tries: int = 3) -> requests.Response:
    last_error = None
    for _ in range(max_tries):
        proxy = next(rotation)
        try:
            r = requests.get(
                url,
                proxies={"http": proxy, "https": proxy},
                timeout=30,
            )
            if r.status_code == 407:  # proxyauthenticatie mislukt
                raise requests.RequestException("proxy auth rejected")
            return r
        except requests.RequestException as exc:
            last_error = exc  # dode of trage proxy: probeer de volgende
    raise RuntimeError(f"all attempts failed for {url}: {last_error}")

Twee details zijn hier belangrijk. Ten eerste moet een dode proxy opnieuw worden geprobeerd via een ander adres, niet via hetzelfde. Ten tweede moet een request dat faalt met een authenticatiefout stoppen en worden gemeld, in plaats van de hele pool door te lopen.

Houd de gezondheid van proxies bij

Een eenvoudige round robin blijft verkeer sturen naar een proxy die is gaan falen. Houd per adres een eenvoudige score bij: tel recente fouten, en haal een adres voor een afkoelperiode uit de pool zodra het een drempel overschrijdt. Laat het later terugkomen en houd het in de gaten. Je scraper besteedt zijn requests dan aan het gezonde deel van de pool.

Log de gebruikte proxy bij elk resultaat. Wanneer een site blokkades begint terug te geven, wil je weten of één adres, één regio of de hele pool de oorzaak is.

De pool in het tempo houden

Rotatie spreidt de belasting over adressen, maar elk adres heeft nog steeds een limiet. Stel een vertraging per adres in, en een globale limiet op het aantal requests per seconde over de hele pool. Rotatie is geen vrijbrief om meer verkeer te sturen. Het is een manier om het verkeer van één adres binnen redelijke grenzen te houden.

Veelgemaakte fouten

De meeste rotatieproblemen komen door een paar gewoonten. Het adres wisselen midden in een login- of afrekenflow breekt de sessie en maakt de site verdacht. Een 429-antwoord is een snelheidslimiet van de site, niet een kapotte proxy, dus meteen naar een nieuw adres overschakelen en opnieuw proberen verspreidt het probleem alleen. Het adres bij elk request wijzigen terwijl je dezelfde cookies behoudt is ook inconsistent, want de cookies zijn aan een andere bezoeker uitgegeven. Ten slotte vult een pool die nooit wordt gecontroleerd zich stilletjes met dode adressen, en stijgt je foutpercentage zonder duidelijke oorzaak. Controleer de pool volgens een schema en verwijder wat faalt.

Proxies en captchaoplossing

Sommige captchataken kunnen de proxy gebruiken die je scraper gebruikt. Je geeft die mee in het optionele veld proxy, in de vorm http://user:pass@host:port, en de solve gebeurt via hetzelfde netwerkpad als je paginaverzoek. Proxyless-taken slaan dat veld helemaal over. Welke je kiest, hangt af van de vraag of de site de captcha aan het netwerkadres bindt, en die afweging wordt uitgelegd in proxy versus proxyless captcha.

Twee praktische punten:

Het live captchatype bij Scarnox is vandaag PopularCaptcha. De PopularCaptcha-gids voor Python laat het verzoek zien en hoe je het teruggegeven token indient.

Kies je proxies

Het type adres dat je roteert is net zo belangrijk als de rotatie zelf. Datacenteradressen zijn snel en goedkoop per request, maar scoren vaak laag. Residentiële adressen scoren beter en zijn trager. De gids residentiële versus datacenter-proxies vergelijkt ze uitgebreider, en het advies daar geldt ook voor de pool die je hier opbouwt.

Scrape verantwoord

Volgende stappen

Start met gratis proefkrediet, zonder creditcard: maak een account aan en test de PopularCaptcha-flow met je eigen proxy. Voor de actuele tarieven zie de prijspagina.