Rotazione proxy in Crawlee per Python: guida completa con proxy residenziali

Scopri come configurare la rotazione proxy in Crawlee per Python usando ProxyConfiguration, SessionPool e proxy residenziali ProxyHat per superare blocchi anti-bot in produzione.

Proxy Rotation in Crawlee for Python: A Developer's Guide to Residential IPs

Se stai costruendo crawler di produzione con Crawlee per Python, prima o poi ti imbatterai in blocchi IP, challenge JavaScript e rate limiting. La rotazione proxy in Crawlee per Python non è un accessorio opzionale: è la differenza tra un crawler che raccoglie 10.000 pagine senza intoppi e uno che muore dopo 200 richieste con un 403. In questa guida vediamo come integrare proxy residenziali ProxyHat nel modo idiomatico — attraverso ProxyConfiguration, SessionPool e middleware nativi del framework — senza hack o workaround fragili.

Avviso legale: raccogli solo dati pubblicamente accessibili, rispetta robots.txt, i limiti di frequenza e i Termini di Servizio. Il Computer Fraud and Abuse Act (CFAA) negli Stati Uniti e il GDPR in Europa possono applicarsi all'accesso non autorizzato o al trattamento di dati personali. Preferisci sempre API ufficiali quando disponibili.

Architettura di Crawlee per Python e ruolo della rotazione proxy

Crawlee per Python offre due motori principali: BeautifulSoupCrawler per richieste HTTP veloci e parsing HTML, e PlaywrightCrawler per rendering headless completo. Entrambi pescano da una coda di richieste unificata (RequestQueue o RequestList), condividendo la stessa infrastruttura di gestione sessioni, proxy e retry. L'autoscaling è integrato: il pool di worker si espande o si contrae in base alla CPU e alla memoria disponibili, fino a un limite configurabile.

Il cuore della gestione IP è il SessionPool. Ogni Session lega insieme cookie, fingerprint del browser (nel caso di Playwright) e un proxy URL. Quando una sessione viene ritirata (session.retire()), Crawlee scarta cookie e IP associati, creando una nuova identità pulita. Questo è il motivo per cui la crawlee session pool e la crawlee proxyconfiguration devono essere pensate insieme: una senza l'altra non basta.

Perché il SessionPool lega IP e cookie

I sistemi anti-bot come Cloudflare Bot Management e DataDome non guardano solo l'IP: correlano IP, header TLS, comportamento di navigazione e pattern di richieste. Se ruoti l'IP ma mantieni i cookie di una sessione bloccata, il nuovo IP eredita la reputazione compromessa. Crawlee risolve questo problema associando ogni sessione a un proxy unico, in modo che il ritiro di una sessione pulisca simultaneamente cookie e IP.

ProxyConfiguration: l'approccio idiomatico in Crawlee

La classe ProxyConfiguration è il punto di integrazione ufficiale per i proxy in Crawlee. Accetta una lista di URL proxy o una funzione generatrice, e fornisce il metodo new_url(session_id=...) che restituisce un URL proxy legato a una specifica sessione. Questo è fondamentale per i proxy residenziali: permette di pinmare un IP residenziale per sessione invece di ruotare ad ogni richiesta.

Due strategie principali:

  • Round-robin: ogni richiesta ottiene un IP diverso. Utile per scraping massivo su target tolleranti, ma rompe la continuità delle sessioni (carrelli, login, paginazione autenticata).
  • Session-bound (sticky): ogni Session ottiene un IP residenziale stabile tramite session_id. L'IP cambia solo quando la sessione viene ritirata. Ideale per siti che richiedono coerenza IP-cookie.

Con ProxyHat, la rotazione si implementa direttamente nel username: il flag -session-abc123 pinma l'IP per quella sessione, mentre -country-US geolocalizza il traffico. Vediamo il codice.

Configurazione base di ProxyConfiguration con ProxyHat

Ecco un esempio minimale di crawlee python proxy con ProxyHat, usando il gateway HTTP su gate.proxyhat.com:8080:

from crawlee.proxy_configuration import ProxyConfiguration

# Genera URL proxy con IP residenziale statunitense
# e sessione pinmata per coerenza IP-cookie
proxy_config = ProxyConfiguration(
    proxy_urls=[
        'http://user-country-US-session-abc123:pass@gate.proxyhat.com:8080',
        'http://user-country-US-session-def456:pass@gate.proxyhat.com:8080',
        'http://user-country-US-session-ghi789:pass@gate.proxyhat.com:8080',
    ]
)

# new_url(session_id='abc123') restituisce sempre lo stesso URL proxy
# per quella session_id, garantendo IP stabile</pre></code>

<p>Quando passi <code>session_id='abc123'</code> a <code>new_url()</code>, Crawlee seleziona deterministicamente l'URL proxy corrispondente. Se invece ometti <code>session_id</code>, Crawlee fa round-robin tra gli URL disponibili. Per un controllo più fine, puoi passare una funzione custom a <code>ProxyConfiguration</code>.</p>

<h2>Esempio eseguibile: BeautifulSoupCrawler con proxy residenziali</h2>

<p>Vediamo un esempio completo di <strong>crawlee proxy rotation</strong> con <code>BeautifulSoupCrawler</code>, <code>ProxyConfiguration</code> e sessioni pinmate su IP residenziali ProxyHat:</p>

<pre><code>import asyncio
from crawlee.beautifulsoup_crawler import BeautifulSoupCrawler
from crawlee.proxy_configuration import ProxyConfiguration
from crawlee.sessions import SessionPool

def make_proxy_url(session_id: str) -> str:
    """Genera un URL proxy ProxyHat con IP residenziale US e sessione pinmata."""
    return f'http://user-country-US-session-{session_id}:pass@gate.proxyhat.com:8080'

async def main():
    # Configurazione proxy con generatore dinamico di URL per sessione
    proxy_config = ProxyConfiguration(
        proxy_urls=[make_proxy_url(f'sess-{i}') for i in range(20)]
    )

    crawler = BeautifulSoupCrawler(
        proxy_configuration=proxy_config,
        max_request_retries=3,
        max_requests_per_crawl=500,
        request_handler_timeout=60,
    )

    @crawler.router.default_handler
    async def handler(request, session, soup):
        title = soup.select_one('title')
        print(f'[{session.id}] {request.url} -> {title.text if title else "N/A"}')

        # Salva i dati estratti
        await crawler.push_data({
            'url': request.url,
            'title': title.text if title else '',
        })

    await crawler.run(['https://example.com/page-1', 'https://example.com/page-2'])

if __name__ == '__main__':
    asyncio.run(main())

In questo esempio, Crawlee assegna automaticamente una sessione ad ogni richiesta. Il SessionPool interno crea fino a 20 sessioni (una per ogni URL proxy), e ogni sessione mantiene il proprio IP residenziale stabile grazie al flag -session-sess-N nel username ProxyHat. Quando una sessione viene ritirata, il successivo new_url() per quella sessione genererà un nuovo endpoint.

Generazione dinamica di username per sessione

Per scalare a centinaia di sessioni, puoi generare gli URL proxy dinamicamente invece di hardcodarli. Ecco un pattern più avanzato che usa una funzione custom:

import hashlib

def proxy_url_generator():
    """Genera URL proxy unici per ogni sessione, con geo-targeting US."""
    counter = 0
    while True:
        session_id = hashlib.md5(f'sess-{counter}'.encode()).hexdigest()[:12]
        yield f'http://user-country-US-session-{session_id}:pass@gate.proxyhat.com:8080'
        counter += 1

# Usa il generatore con ProxyConfiguration
proxy_config = ProxyConfiguration(
    proxy_urls=list(proxy_url_generator())[:50]  # 50 sessioni uniche
)

Questo pattern ti permette di generare 100 sessioni concorrenti o più, ciascuna con un IP residenziale distinto. La latenza tipica dei proxy residenziali ProxyHat si aggira tra 200–800 ms per richiesta, rispetto ai 50–150 ms dei datacenter — ma il trade-off vale la pena quando i target bloccano i range IP datacenter.

Perché i proxy residenziali battono i datacenter su Cloudflare e DataDome

I proxy datacenter offrono velocità e costi inferiori, ma i loro range IP appartengono a ASN noti (AWS, DigitalOcean, Hetzner). I sistemi anti-bot come Cloudflare Bot Management e DataDome mantengono database di ASN datacenter e assegnano automaticamente un punteggio di rischio elevato a queste richieste. Il risultato: challenge JavaScript, CAPTCHA o blocchi 403 immediati.

I proxy residenziali usano IP assegnati a ISP reali (Comcast, AT&T, Vodafone), con reputazione di traffico umano. Una richiesta da un IP residenziale statunitense con header coerenti e sessione stabile è statisticamente indistinguibile da un utente reale. Il tasso di successo tipico su target protetti passa dal 30–50% con datacenter al 85–95% con residenziali ben gestiti.

Caratteristica Proxy Datacenter Proxy Residenziali
Latenza tipica 50–150 ms 200–800 ms
Costo per GB $0.5–2 $3–15
Tasso di successo su Cloudflare 30–50% 85–95%
Rischio di blocco ASN Alto Basso
Coerenza sessione Limitata Ottima con sticky session

Proxy a livelli (tiered fallback)

In produzione, una strategia efficace è il tiered proxy fallback: inizia con datacenter per target non protetti, passa a residenziali al primo segnale di blocco, e usa mobile proxy come ultima risorsa per i target più aggressivi. Crawlee supporta questo pattern tramite il ritiro dinamico delle sessioni e la rigenerazione dell'URL proxy.

from crawlee.sessions import Session

@crawler.router.default_handler
async def handler(request, session, soup, response):
    # Rileva blocco: status 403, 429, o challenge page
    if response.status_code in (403, 429):
        print(f'Blocco rilevato su {request.url} — ritiro sessione {session.id}')
        session.retire()  # Scarta IP + cookie + fingerprint
        raise ValueError(f'Blocked: {response.status_code}')

    # Verifica presenza di challenge Cloudflare/DataDome nel HTML
    if soup.select_one('#cf-challenge-running, #datadome-challenge'):
        session.retire()
        raise ValueError('Anti-bot challenge detected')

    # Estrazione normale
    title = soup.select_one('title')
    await crawler.push_data({
        'url': request.url,
        'title': title.text if title else '',
    })

Quando session.retire() viene chiamato, Crawlee marca la sessione come "retired" e non la riutilizza. La richiesta viene rimessa in coda e al prossimo tentativo riceve una nuova sessione con un nuovo IP residenziale. Con max_request_retries=3, Crawlee prova fino a 3 volte con sessioni diverse prima di dichiarare fallita la richiesta.

Pattern di produzione: concorrenza, retry e gestione errori

Concorrenza tramite autoscaled pool

Crawlee gestisce la concorrenza automaticamente attraverso l'AutoscaledPool. I parametri chiave sono max_concurrency (numero massimo di richieste parallele) e min_concurrency. Per proxy residenziali, ti consigliamo di partire con max_concurrency=10–20 e aumentare gradualmente monitorando il tasso di successo.

crawler = BeautifulSoupCrawler(
    proxy_configuration=proxy_config,
    max_request_retries=3,
    max_requests_per_crawl=10000,
    max_request_retries=3,
    autoscaled_pool_options={
        'max_concurrency': 15,
        'min_concurrency': 5,
    },
    request_handler_timeout=60,
)

Gestione errori nel request_handler

Oltre al rilevamento di blocchi, il request_handler deve gestire timeout di rete, connessioni fallite e parsing error. Crawlee distingue tra errori retryable (network timeout, 503) e non retryable (404, parsing fallito). Sollevare un'eccezione nel handler mette automaticamente la richiesta in retry, a meno che tu non usi request.no_retry = True.

@crawler.router.default_handler
async def handler(request, session, soup, response):
    try:
        data = extract_data(soup)
        if not data:
            # Dato mancante: non ritentare, è un problema di contenuto
            request.no_retry = True
            return
        await crawler.push_data(data)
    except Exception as e:
        # Errore generico: ritira sessione e ritenta
        session.retire()
        raise

Monitoraggio e metriche

In produzione, monitora almeno queste metriche:

  • Tasso di successo per sessione (successi / tentativi totali).
  • Latenza P50 e P95 per capire se i proxy sono il collo di bottiglia.
  • Numero di sessioni attive vs ritirate per rilevare ban IP sistematici.
  • Richieste al minuto per restare sotto i limiti di frequenza del target.

Se vedi più del 20% di sessioni ritirate in 5 minuti, il target sta bloccando aggressivamente. Riduci la concorrenza, aumenta il ritardo tra le richieste, o passa a proxy con geo-targeting più specifico (città invece di paese).

Quando NON usare il browser crawling

Il PlaywrightCrawler è potente ma costoso: ogni pagina richiede avvio del browser, rendering JavaScript, e consumo di memoria 10–50x superiore rispetto a BeautifulSoupCrawler. Usalo solo quando:

  • Il contenuto è generato dinamicamente via JavaScript (SPA, React, Vue).
  • Il target richiede interazione (click, scroll, compilazione form).
  • I sistemi anti-bot richiedono un fingerprint browser completo.

Per la maggior parte dei casi di web scraping e SERP tracking, BeautifulSoupCrawler con proxy residenziali è sufficiente e 5–10x più veloce. Se il target serve il HTML completo nella risposta HTTP, il browser è sprecato.

Considerazioni etiche e legali

Prima di avviare qualsiasi crawler, verifica:

  1. robots.txt: Crawlee può rispettare automaticamente robots.txt tramite configurazione. Non disabilitarlo senza motivo.
  2. Termini di Servizio: molti siti proibiscono esplicitamente lo scraping. Leggi i ToS.
  3. Rate limiting: mantieni una frequenza ragionevole. 1–5 richieste al secondo per dominio è una buona regola empirica.
  4. Dati personali: il GDPR richiede base giuridica per il trattamento di dati personali. Se raccogli dati personali di utenti UE, consulta un legale.
  5. API ufficiali: se il target offre un'API, usala. È più stabile, più veloce e legalmente più sicura.

Configurazione ProxyHat in Crawlee

ProxyHat offre proxy residenziali, mobile e datacenter con geo-targeting a livello di paese e città. L'integrazione con Crawlee avviene interamente tramite ProxyConfiguration, senza SDK aggiuntivi. I parametri di connessione sono:

  • Gateway HTTP: gate.proxyhat.com:8080
  • Gateway SOCKS5: gate.proxyhat.com:1080
  • Geo-targeting: user-country-US o user-country-DE-city-berlin
  • Sessione pinmata: user-session-abc123

Consulta la documentazione ufficiale ProxyHat per i dettagli completi sui parametri disponibili. Per i prezzi e i piani, visita la pagina prezzi di ProxyHat.

Key Takeaways

  • SessionPool e ProxyConfiguration vanno pensati insieme: ogni sessione lega IP, cookie e fingerprint. Ritirare una sessione pulisce tutto simultaneamente.
  • Usa new_url(session_id=...) per IP stabili: i proxy residenziali con sessioni pinmate battono il round-robin su target protetti.
  • Residenziali > datacenter su Cloudflare/DataDome: il tasso di successo passa dal 30–50% all'85–95%.
  • Chiama session.retire() sui blocchi: non ritentare con la stessa sessione. Crawlee rimetterà la richiesta in coda con una sessione nuova.
  • Parti con BeautifulSoupCrawler: usa PlaywrightCrawler solo quando il rendering JS è indispensabile. Il costo in memoria è 10–50x superiore.
  • Rispetta robots.txt, ToS e rate limit: il CFAA e il GDPR si applicano allo scraping. Preferisci API ufficiali quando disponibili.

FAQ

Cos'è la rotazione proxy in Crawlee per Python?

La rotazione proxy in Crawlee per Python è la gestione automatica degli IP proxy attraverso la classe ProxyConfiguration e il SessionPool. Crawlee assegna un proxy URL a ogni sessione, permettendo sia round-robin (IP diverso per richiesta) sia sticky session (IP stabile per sessione tramite new_url(session_id=...)). Il ritiro di una sessione scarta automaticamente IP e cookie associati.

Perché la rotazione proxy in Crawlee per Python è importante?

È importante perché i sistemi anti-bot come Cloudflare e DataDome correlano IP, cookie e fingerprint per rilevare bot. Senza rotazione, un singolo IP viene bloccato dopo poche richieste. Con proxy residenziali e sessioni pinmate, ogni sessione mantiene un'identità coerente che appare come traffico umano, aumentando il tasso di successo dal 30–50% al 85–95%.

Quale tipo di proxy funziona meglio per la rotazione in Crawlee?

I proxy residenziali funzionano meglio per target protetti da anti-bot, perché usano IP di ISP reali con reputazione di traffico umano. I proxy datacenter sono più veloci e economici ma vengono bloccati facilmente dai sistemi anti-bot che riconoscono gli ASN datacenter. Una strategia tiered (datacenter → residenziali → mobile) offre il miglior compromesso tra costo e affidabilità.

Come evitare i blocchi nella rotazione proxy con Crawlee?

Per evitare i blocchi: usa session.retire() quando rilevi status 403/429 o challenge anti-bot, mantieni max_request_retries=3 per ritentare con sessioni nuove, limita la concorrenza a 10–20 richieste parallele con proxy residenziali, rispetta i rate limit del target (1–5 req/s per dominio), e usa geo-targeting specifico (città invece di paese) quando possibile.

Pronto per iniziare?

Accedi a oltre 50M di IP residenziali in oltre 148 paesi con filtraggio AI.

Vedi i prezziProxy residenziali
← Torna al Blog