Come configurare un proxy personalizzato in Scrapy (pronto per la produzione)

Ultimo aggiornamento il August 11, 2026
Hand-drawn Scrapy crawler routing through a proxy pool, retrying a 503 route and completing through a 200 route
Riepilogo AI
- Crea un middleware proxy personalizzato per Scrapy che assegni percorsi approvati, aggiunga l'autenticazione in modo sicuro, registri i motivi dei fallimenti e preservi i metadati della richiesta durante i retry. - Comprendi l'ordine dei middleware del downloader, soprattutto come la logica proxy personalizzata interagisce con HttpProxyMiddleware, RetryMiddleware, i redirect e la gestione delle eccezioni. - Aggiungi rotazione con tentativi limitati, periodi di cooldown, stato di salute dei proxy e policy consapevoli del target invece di scegliere un proxy casuale per ogni richiesta. - Distingui tra fallimenti di autenticazione del proxy, errori di connessione, problemi DNS, risposte 403 del target e rate limit, così che ogni condizione riceva la risposta corretta. - Usa protezioni di produzione per l'archiviazione dei segreti, la concorrenza, l'osservabilità, la coerenza della sessione e il comportamento fail-closed quando nessun proxy approvato resta disponibile.

Il tuo spider Scrapy parte a razzo su 100 pagine di test, poi si schianta quando arriva a quota 10.000. In realtà non è davvero un bug di scraping: è un problema di rete mascherato da bug di scraping. La soluzione a cui tutti ricorrono è un proxy, e inserirlo in request.meta ti prende più o meno trenta secondi.

Il problema è che quella soluzione da trenta secondi è proprio il punto in cui molti tutorial si fermano. Ti mostrano meta={"proxy": "http://IP:PORT"}, magari una classe middleware, e considerano il lavoro chiuso. Però spesso saltano i casi veri: cosa succede quando il proxy muore a metà crawl, come evitare che le credenziali finiscano nella cronologia di Git, o perché un retry può riusare lo stesso proxy fallito. Sono proprio queste esigenze di produzione che questa guida affronta: configurazione fail-closed, gestione dei segreti, selezione intenzionale del proxy nei retry, limiti di protocollo e trade-off di costo misurabili.

Cos'è un Proxy Middleware in Scrapy?

Un proxy middleware è un pezzo di codice che si inserisce nella pipeline di download di Scrapy e decide da quale indirizzo IP una richiesta deve sembrare arrivare, prima che venga mandata in rete. Scrapy include già un middleware integrato, HttpProxyMiddleware, che legge la chiave proxy da request.meta, aggiunge l’autenticazione del proxy se serve e passa la richiesta al download handler che apre davvero la connessione. Un proxy middleware personalizzato non sostituisce quel passaggio di trasporto: è un selettore che sceglie quale proxy usare prima che entri in gioco il meccanismo integrato. La differenza conta più di quanto sembri, ed è spesso la radice della maggior parte dei ticket del tipo "il mio middleware personalizzato non funziona".

Perché i Proxy Sono Importanti nei Progetti Scrapy in Produzione

Un proxy modifica il percorso di rete e l’IP sorgente apparente. Può essere utile per test geografici legittimi, per distribuire traffico autorizzato e per isolare guasti di rete. Non dà permessi, non aggira i rate limit e non garantisce l’accesso. Se un crawl ha davvero bisogno di un proxy dipende dal target, dai suoi termini, dalla frequenza delle richieste e dai requisiti di affidabilità del job.

Non tutti i proxy sono uguali, e scegliere il livello sbagliato è già di per sé un incidente di produzione:

Tipo di proxyAffidabilitàVelocitàRischio di rilevamentoCosto tipico
Proxy pubblici gratuitiMolto variabileVariabileSpesso elevatoNessun costo, ma rischio operativo e di sicurezza concreto
Proxy datacenterDipende dal provider e dal targetSpesso velociDipende dal targetDi solito a GB o per IP
Proxy residentialDipende dal provider e dal targetVariabileDipende dal targetDi solito a GB
Proxy ISPDipende dal provider e dal targetVariabileDipende dal targetSpecifico del provider

Vale la pena fare una nota specifica sui proxy gratuiti perché i rischi osservati sono tutt’altro che banali. Lo studio di 30 mesi Free Proxies Unmasked ha monitorato oltre 640.000 indirizzi di 11 provider: il 34,5% è stato attivo almeno una volta e 16.923 hanno alterato i contenuti. Questi dati sono un avvertimento forte per le liste pubbliche; non sono un tasso di fallimento valido per ogni lista attuale, pool a pagamento, target o carico di lavoro.

In più, i proxy non aggirano magicamente i moderni sistemi di bot detection. Servizi come Cloudflare valutano le richieste usando decine di segnali — fingerprint TLS, coerenza degli header, esecuzione JavaScript, pattern comportamentali — dove l’IP è solo uno dei fattori. Un proxy residential pulito, ma usato in una richiesta con header incoerenti e senza cookie jar, verrà comunque segnalato. Tieni ben presenti queste aspettative prima di costruire un’intera architettura basata sul semplice "ruoto l’IP".

Prima di Iniziare

  • Difficoltà: Intermedia
  • Tempo richiesto: ~30–45 minuti per la configurazione completa in produzione, ~5 minuti per il test rapido
  • Cosa ti serve: Python 3.9+, Scrapy installato (questa guida è testata su Scrapy 2.17.0, rilasciato nel luglio 2026), uno spider funzionante creato con scrapy startproject e almeno un endpoint proxy (per i test va benissimo una trial gratuita di qualunque provider di proxy datacenter)

Passo 1: Testare un Proxy con il Parametro Request Meta

Il modo più veloce per verificare che un proxy funzioni è aggirare del tutto l’architettura dei middleware e provarlo direttamente.

Il HttpProxyMiddleware integrato in Scrapy legge la chiave proxy direttamente da request.meta e instrada la richiesta attraverso quel proxy. Nessuna modifica alle impostazioni, nessuna classe middleware: basta un solo argomento keyword.

import scrapy

class ProxyTestSpider(scrapy.Spider):
    name = "proxy_test"
    start_urls = ["https://httpbin.org/ip"]

    def start_requests(self):
        for url in self.start_urls:
            yield scrapy.Request(
                url,
                meta={"proxy": "http://203.0.113.10:8080"},
                callback=self.parse,
            )

    def parse(self, response):
        self.logger.info(response.text)

Eseguilo con scrapy runspider proxy_test.py. Se il proxy funziona, httpbin.org/ip restituirà l’IP del proxy invece del tuo: quella è la conferma. Se invece la risposta si blocca e alla fine compare un errore TCP connection timed out, il proxy è morto o irraggiungibile, cosa che — sorpresa — succede più spesso di quanto i vendor di proxy ammettano.

Questo metodo va bene per spider usa-e-getta o test rapidi. Diventa ingestibile appena hai più di uno spider, perché a quel punto stai scrivendo la stessa stringa proxy in cinque file diversi.

Passo 2: Creare un Proxy Middleware Personalizzato

Per tutto ciò che va oltre uno spider singolo, conviene centralizzare la logica del proxy in un solo punto. Crea una classe ProxyMiddleware nel file middlewares.py del progetto:

from scrapy.exceptions import NotConfigured

class ProxyMiddleware:
    def __init__(self, proxy_url):
        self.proxy_url = proxy_url

    @classmethod
    def from_crawler(cls, crawler):
        proxy_url = crawler.settings.get("PROXY_URL")
        if not proxy_url:
            raise NotConfigured("PROXY_URL è obbligatorio; nessun fallback diretto silenzioso")
        return cls(proxy_url=proxy_url)

    def process_request(self, request, spider):
        if "proxy" not in request.meta:
            request.meta["proxy"] = self.proxy_url

E registrala in settings.py:

import os

PROXY_URL = os.environ.get("PROXY_URL")

DOWNLOADER_MIDDLEWARES = {
    "myproject.middlewares.ProxyMiddleware": 350,
}

Nota il metodo di classe from_crawler invece di un semplice __init__. È il pattern che Scrapy raccomanda davvero per leggere le impostazioni, ed è lo stesso hook che useremo di nuovo al Passo 4 quando parleremo dei segreti. Il vantaggio qui è chiarissimo: cambi una sola impostazione e tutti gli spider del progetto usano il nuovo proxy. Niente più caccia all’IP vecchio in cinque file diversi.

Passo 3: Capire l'Ordine di Esecuzione dei Middleware (Così il Proxy Non Sembra Inattivo)

Qui c’è la parte che quasi tutti i tutorial liquidano con un "metti la priorità a 350, fidati". I downloader middleware di Scrapy seguono un ordine preciso e prevedibile, e se non lo capisci il setup proxy ti produrrà bug che sembrano non c’entrare nulla con i proxy.

Gli hook lato richiesta (process_request) vengono eseguiti in ordine di priorità crescente — prima il numero più basso. Gli hook lato risposta (process_response, process_exception) vengono eseguiti in ordine decrescente — prima il numero più alto, risalendo la catena al contrario.

Flusso richiesta (crescente):
  Spider → [100] RobotsTxt → [300] HttpAuth → [350] IL TUO PROXY MIDDLEWARE
         → [500] UserAgent → [550] Retry → [700] Cookies → [750] HttpProxy
         → Downloader

Flusso risposta (decrescente):
  Downloader → [750] HttpProxy → [700] Cookies → [550] Retry
             → [500] UserAgent → [350] IL TUO PROXY MIDDLEWARE → [300] HttpAuth
             → [100] RobotsTxt → Spider

Ecco la tabella reale e aggiornata delle priorità di default dei middleware integrati di Scrapy (verificata su 2.17.0):

MiddlewarePriorità predefinita
RobotsTxtMiddleware100
HttpAuthMiddleware300
DownloadTimeoutMiddleware350
DefaultHeadersMiddleware400
UserAgentMiddleware500
RetryMiddleware550
RedirectMiddleware600
CookiesMiddleware700
HttpProxyMiddleware750
DownloaderStats850
HttpCacheMiddleware900

Quando RetryMiddleware programma un retry, copia la richiesta fallita — inclusi i metadati — e quella nuova richiesta rientra nella catena dei downloader middleware. Il rapporto numerico del selettore con la priorità 550 non garantisce la rotazione. La rotazione avviene solo quando il codice del selettore riconosce il retry e sovrascrive in modo intenzionale il meta["proxy"] copiato. La priorità 350 è un punto comodo per un selettore perché entra in gioco prima del passaggio di trasporto integrato a 750, ma da sola non è un meccanismo di rotazione.

Percorsi di richiesta e risposta di Scrapy attraverso le priorità 350, 550 e 750, con un retry 503 che rientra nella catena dei middleware

Errori Comuni nell'Ordinamento dei Middleware

  • Impostare il middleware alla stessa priorità di HttpProxyMiddleware (750): crea una race condition in cui è l’ordine del dict di Scrapy — non la tua logica — a decidere quale middleware processa prima la richiesta. Sintomo: comportamento del proxy intermittente e inspiegabile.
  • Usare setdefault() o if "proxy" not in request.meta in un selettore con rotazione: il retry copiato conserva il proxy precedente. Sintomo: ogni retry ripete lo stesso percorso fallito. Soluzione: rilevare un retry (per esempio, retry_times > 0) e sostituire esplicitamente il valore proxy gestito dal selettore.
  • Disabilitare del tutto HttpProxyMiddleware: alcuni tutorial suggeriscono di impostare "scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware": None perché "ci pensa il middleware personalizzato". In realtà no: il middleware personalizzato è un selettore, non uno strato di trasporto. Disabilitare quello integrato significa che gli header di autenticazione del proxy non vengono mai aggiunti e le richieste escono senza autenticazione (o non escono affatto).

Passo 4: Smettere di Hardcodare le Credenziali del Proxy

Ogni tutorial Scrapy sui proxy che compare in alto scrive http://username:password@proxy.example.com:8080 direttamente in un file Python. Quella è una credenziale che resta per sempre nella cronologia di Git, in ogni clone, in ogni fork, in ogni dump di log se qualcuno usa con leggerezza dei print().

In pratica ci sono tre livelli per farlo:

MetodoSicurezzaFlessibilitàIdeale per
Hardcoded in spider/settings.pyDebole — i segreti restano nel repoBassaSolo test locali rapidi
Variabile d'ambiente http_proxy (nativa di Scrapy)Migliore — fuori dal codiceBassa (un solo proxy)Pipeline CI/CD, Docker
File .env + python-dotenv + from_crawlerLa migliore — fuori dal codice, per ambienteAlta (più proxy, rotazione)Scraper in produzione

La terza opzione vale la pena farla bene. Installa python-dotenv, crea un file .env e aggiungilo subito a .gitignore — davvero, fallo adesso:

PROXY_USER=myuser
PROXY_PASSWORD=my$ecret!Pass
PROXY_HOST=proxy.example.com
PROXY_PORT=8080

Caricalo all’inizio di settings.py:

from dotenv import load_dotenv
import os

load_dotenv()

PROXY_USER = os.getenv("PROXY_USER")
PROXY_PASSWORD = os.getenv("PROXY_PASSWORD")
PROXY_HOST = os.getenv("PROXY_HOST")
PROXY_PORT = os.getenv("PROXY_PORT")

Poi leggilo in modo sicuro nel middleware tramite from_crawler — è il pattern che risolve esattamente la confusione che vedo spesso nei forum, dove la domanda è: "come faccio a impostarlo prima di eseguire scrapy crawl se le credenziali cambiano a ogni run?":

import os
from urllib.parse import quote

class SecureProxyMiddleware:
    def __init__(self, user, password, host, port):
        self.user = quote(user, safe="")
        self.password = quote(password, safe="")
        self.host = host
        self.port = port

    @classmethod
    def from_crawler(cls, crawler):
        settings = crawler.settings
        return cls(
            user=settings.get("PROXY_USER"),
            password=settings.get("PROXY_PASSWORD"),
            host=settings.get("PROXY_HOST"),
            port=settings.get("PROXY_PORT"),
        )

    def process_request(self, request, spider):
        proxy_url = f"http://{self.user}:{self.password}@{self.host}:{self.port}"
        request.meta["proxy"] = proxy_url

Nota la chiamata a urllib.parse.quote() attorno alle credenziali. Se la password contiene @, : o / (e i generatori di password adorano metterli), il parsing dell’URL si rompe a meno che non vengano percent-encoded prima. È una correzione di una sola riga che ti evita un’ora imbarazzante di debug di errori "invalid proxy URL" che non hanno nulla a che vedere con il proxy in sé.

Tieni le credenziali fuori dai log e verifica il percent-encoding con valori rappresentativi ma finti. HTTPS tunneling, SOCKS5 e credenziali non latine hanno limiti che dipendono dall’handler; non dare per scontato che un pattern di autenticazione funzioni ovunque senza un test di integrazione bloccato su quella configurazione specifica.

Flusso sicuro da un file di ambiente protetto, passando per impostazioni proxy con percent-encoding, fino ai metadati di richiesta di Scrapy

Passo 5: Aggiungere la Rotazione dei Proxy

Un singolo proxy — anche se buono — che fa 5.000 richieste sullo stesso sito prima o poi viene segnalato. Ti serve un pool.

Opzione A — costruirlo da solo. È davvero semplice:

import random

class RotatingProxyMiddleware:
    def __init__(self, proxy_pool):
        self.proxy_pool = proxy_pool

    @classmethod
    def from_crawler(cls, crawler):
        return cls(proxy_pool=crawler.settings.getlist("PROXY_POOL"))

    def process_request(self, request, spider):
        request.meta["proxy"] = random.choice(self.proxy_pool)

Questo funziona per usi basilari ma non sa nulla di quali proxy siano davvero vivi. Stai tirando i dadi a ogni richiesta.

Opzione B — usare scrapy-rotating-proxies. Questo pacchetto di terze parti aggiunge di default il rilevamento dei ban e il backoff automatico:

pip install scrapy-rotating-proxies

Qui però devo essere onesto: l'ultima release su PyPI è la versione 0.6.2, datata 2019, e il progetto è etichettato come Alpha. Non vuol dire per forza che sia rotto con le versioni moderne di Scrapy, ma "non mantenuto attivamente dal 2019" non equivale a "collaudato per il traffico di produzione del 2026". Blocca la versione, testalo sui target reali e non dare per scontato che gestisca endpoint proxy autenticati — in gran parte non lo fa.

Passo 6: Costruire un Middleware Proxy Tollerante ai Guasti (Rilevamento dei Proxy Morti)

Questa è la sezione che ogni tutorial concorrente salta del tutto, ed è la differenza tra una demo e qualcosa che regge un crawl di 6 ore senza supervisione.

ScenarioCosa mostrano la maggior parte dei tutorialCosa aggiunge questo middleware
Il proxy restituisce 407Non trattatoLo considera un fallimento di autenticazione del proxy
Il target restituisce 403/429Spesso raggruppati insiemeMantiene separati i segnali di policy/rate limit dallo stato del proxy
Il proxy va in timeoutNon trattatoSoglia di timeout configurabile, decadimento del punteggio di salute
Tutti i proxy sono mortiNon trattatoFallback graduale o pausa del crawl con warning nel log
Proxy instabile (intermittente)Non trattatoPeriodo di raffreddamento prima di reinserirlo nel pool
import time
import random
from scrapy.exceptions import IgnoreRequest

class FaultTolerantProxyMiddleware:
    MAX_FAILURES = 3
    COOLDOWN_SECONDS = 300

    def __init__(self, proxy_pool):
        self.pool = {p: {"failures": 0, "banned_until": 0} for p in proxy_pool}

    @classmethod
    def from_crawler(cls, crawler):
        return cls(proxy_pool=crawler.settings.getlist("PROXY_POOL"))

    def _healthy_proxies(self):
        now = time.time()
        return [p for p, s in self.pool.items() if s["banned_until"] < now]

    def process_request(self, request, spider):
        healthy = self._healthy_proxies()
        if not healthy:
            spider.logger.warning("Tutti i proxy sono non affidabili — pausa del crawl")
            raise IgnoreRequest("Nessun proxy affidabile disponibile")
        request.meta["proxy"] = random.choice(healthy)

    def process_response(self, request, response, spider):
        proxy = request.meta.get("proxy")
        if proxy and response.status == 407:
            self._mark_failure(proxy)
        return response

    def process_exception(self, request, exception, spider):
        proxy = request.meta.get("proxy")
        if proxy:
            self._mark_failure(proxy)

    def _mark_failure(self, proxy):
        state = self.pool[proxy]
        state["failures"] += 1
        if state["failures"] >= self.MAX_FAILURES:
            state["banned_until"] = time.time() + self.COOLDOWN_SECONDS
            state["failures"] = 0

Alcune note nate dall’averlo costruito davvero: non trattare ogni 403 come prova che il proxy sia morto — RFC 9110 definisce il 403 come "il server ha capito ma rifiuta", il che può benissimo significare che sono sospetti gli header o la sessione, a prescindere dal proxy. Un 407, invece, significa che è il proxy stesso a rifiutare l’autenticazione: un segnale molto più forte e specifico. Mischiare questi segnali nello stesso contenitore è il modo più veloce per bruciare proxy sani senza motivo.

Tieni espliciti in produzione i retry temporanei di Scrapy, così chi legge il codice può vedere chiaramente la policy:

RETRY_HTTP_CODES = [500, 502, 503, 504, 522, 524, 408, 429]
RETRY_TIMES = 2

Questi sono i default di Scrapy 2.17. Non aggiungere in massa 403 o 407: il 403 è un rifiuto del target con molte possibili cause, mentre il 407 è un problema di autenticazione del proxy che un retry generico della richiesta non risolve. Se un contratto specifico del target giustifica il retry di un altro stato, documenta il motivo e testalo separatamente.

Gestione distinta per fallimento di autenticazione 407, rate limit 429, retry 503, successo 200 e cancello chiuso quando i proxy non sono disponibili

Passo 7: Un Pattern Misurato di Proxy-on-Retry

Alcuni target autorizzati possono restituire contenuto valido direttamente e richiedere un proxy solo dopo una risposta transitoria documentata. Questo può ridurre i byte inviati via proxy, ma non esiste una percentuale universale difendibile di risparmio né un tasso portabile di successo delle richieste dirette. Misura il tuo carico di lavoro prima di adottare il pattern.

Usa l’helper pubblico get_retry_request() di Scrapy e limita l’escalation agli stati specifici del target che hai classificato in modo esplicito. Questo esempio tratta 429 e 503 come segnali di pressione che giustificano il retry; esclude volutamente 403 e 407.

from scrapy.downloadermiddlewares.retry import get_retry_request

class CostAwareEscalationMiddleware:
    def process_response(self, request, response, spider):
        if response.status not in {429, 503}:
            return response

        retry = get_retry_request(
            request,
            spider=spider,
            reason=f"proxy_escalation_{response.status}",
            max_retry_times=2,
        )
        if retry is None:
            return response

        current_tier = request.meta.get("proxy_tier", "direct")
        if current_tier == "direct":
            retry.meta["proxy"] = spider.settings["DATACENTER_PROXY"]
            retry.meta["proxy_tier"] = "datacenter"
        elif current_tier == "datacenter":
            retry.meta["proxy"] = spider.settings["RESIDENTIAL_PROXY"]
            retry.meta["proxy_tier"] = "residential"
        else:
            return response
        return retry

Registra il tasso di contenuti validi in accesso diretto, il tasso di contenuti validi tramite proxy, i byte per record andato a buon fine, i retry per successo e la latenza aggiunta. Un design direct-first è accettabile solo quando l’accesso diretto è autorizzato e il sistema fallisce in modo chiuso ogni volta che è richiesto un proxy. Il risparmio è la riduzione misurata del traffico via proxy, non una percentuale presunta.

Quando Gestire i Proxy in Modo Autonomo Non Conviene

Voglio essere chiaro invece di fingere che tutto il resto dell’articolo fosse inutile: tutto ciò che hai letto sopra è vera ingegneria ed è utile, e per molti progetti — crawl ad alto volume, pipeline personalizzate, tutto ciò in cui serve controllo totale sulla schedulazione delle richieste — è la scelta giusta.

Ma se il tuo obiettivo reale è "ottenere dati strutturati da questa pagina" più che "gestire l’infrastruttura proxy", allora un’API di estrazione potrebbe essere il confine migliore. La documentazione attuale di Thunderbit per POST /extract accetta l’URL di una pagina e uno schema JSON opzionale; quando lo schema viene omesso, il servizio può generarlo dal contenuto della pagina. L’endpoint espone anche le modalità di rendering none, basic e full, oltre ai controlli di timeout e di attesa post-caricamento. L’estrazione solo tramite prompt non fa parte della superficie richiesta attualmente supportata, quindi le integrazioni di produzione vanno costruite attorno al contratto documentato dello schema. Questo sposta l’interfaccia di estrazione dietro una sola richiesta; non promette in modo universale di risolvere qualunque target anti-bot o CAPTCHA.

FattoreScrapy + proxy fai-da-teEstrazione via API (es. Thunderbit)
Sforzo inizialeAlto — middleware, rotazione, logica di retryBasso — una chiamata API con uno schema
Comportamento di rete/renderingConfiguri handler, proxy, header e ritardiControllato tramite opzioni API documentate
ManutenzioneGestisci tu selettori, salute del pool e cambi del targetGestisci tu la qualità dello schema, la validazione e il comportamento di integrazione
Modello di costoFee dei proxy + compute + tempo di engineeringLa documentazione attuale indica 20 unità per pagina (verificato 2026-08-10)
ControlloTotale — pipeline personalizzate, catena di middlewareLimitato alle capacità dell'API
Ideale perCrawl complessi, alto volume, logica customEstrazione mirata, prototipazione, enrichment

Se stai soprattutto estraendo pagine strutturate per liste di lead, dati prodotto o ricerca, fai un pilot rappresentativo con la Thunderbit Chrome Extension o con l’API e confronta record validi, latenza, unità e tempo di manutenzione. Se il tuo progetto richiede grafo di crawl personalizzati e controllo della pipeline, Scrapy resta la scelta più forte.

Approfondisci

Consigli e Errori Comuni

  • Consiglio: testa i proxy su httpbin.org/ip prima di puntarli a un target reale. È il modo più rapido per verificare che il routing funzioni prima di aggiungere complessità sopra.
  • Errore comune: impostare un proxy in request.headers invece che in request.meta. È un bug davvero frequente, quasi da refuso: HttpProxyMiddleware legge solo meta["proxy"], e un tentativo basato su header fallisce in silenzio senza errori evidenti.
  • Errore comune: pensare che i proxy HTTP e HTTPS si configurino allo stesso modo. Un URL proxy HTTP verso una destinazione HTTPS in genere funziona tramite tunneling CONNECT con un handler compatibile, ma usare lo schema https:// per l’endpoint del proxy è una configurazione diversa e meno supportata: non confondere le due cose.
  • Consiglio: se ti serve il supporto SOCKS5, controlla prima le capacità del download handler della tua versione di Scrapy. L’handler Httpx sperimentale di Scrapy 2.17 ha aggiunto il supporto SOCKS5 tramite httpx[socks], ma resta etichettato come sperimentale: non costruire una dipendenza di produzione senza test tuoi.

Metodi Alternativi

Oltre a scrapy-rotating-proxies, alcuni team instradano tutta la logica proxy attraverso un gateway del provider — un singolo URL proxy in cui il vendor gestisce dietro le quinte rotazione, stickiness di sessione e geo-targeting. Questo compromesso sacrifica un po’ di controllo in cambio di molta meno logica middleware, e vale la pena confrontarne il costo con quello di un pool gestito in autonomia prima di costruirlo da zero.

Conclusione

Impostare un proxy in Scrapy richiede una sola riga. Far sì che quella configurazione regga un vero crawl di produzione richiede una policy di fallimento esplicita, credenziali protette, limiti degli handler testati e codice selettore che sostituisca consapevolmente i metadati proxy copiati in caso di retry. Se ti porti via due abitudini, fai in modo che siano queste: fallire in modo chiuso quando un proxy è necessario e non committare mai la password di un proxy in un file Python.

FAQ

Come configuro un proxy personalizzato in Scrapy con autenticazione? Usa il formato URL protocol://username:password@host:port, ma prima percent-encode di username e password con urllib.parse.quote() se contengono caratteri speciali. In produzione, leggi quelle credenziali tramite un metodo di classe from_crawler che le recuperi da variabili d’ambiente invece di hardcodarle.

Che numero di priorità dovrei usare per il mio middleware proxy personalizzato in Scrapy? 350 è una priorità comune per un selettore perché viene eseguita prima di HttpProxyMiddleware, che è a 750. Non garantisce la rotazione. Un retry riceve un proxy nuovo solo se il selettore riconosce la richiesta retry copiata e sovrascrive il precedente valore meta["proxy"].

Come gestisco automaticamente i proxy morti in Scrapy? Costruisci un middleware che tenga traccia del numero di fallimenti per proxy in process_response e process_exception, rimuova i proxy dal pool attivo dopo una soglia di fallimento e li reinserisca dopo un periodo di raffreddamento invece di bannarli in modo permanente.

Posso usare Scrapy con proxy SOCKS5? L’HttpxDownloadHandler sperimentale di Scrapy 2.17 documenta il supporto SOCKS5 quando è installato httpx[socks]. Il download handler HTTP/1.1 predefinito non supporta proxy SOCKS. Blocca handler e versione e fai un test di integrazione prima di considerare questo percorso pronto per la produzione.

Quanto può far risparmiare davvero il pattern proxy-on-retry sui costi dei proxy? Non esiste una percentuale portabile. Misura la quota di richieste autorizzate che restituiscono contenuto valido direttamente, i byte inviati tramite ciascun livello proxy, i retry per ogni record andato a buon fine e la latenza aggiunta. La riduzione osservata dei byte via proxy è il tuo risparmio; se l’accesso diretto non è autorizzato o non è valido, non usare questo pattern.

Ke
Ke
CTO di Thunderbit | Senior Data Scientist ed esperto di ML Con quasi un decennio di esperienza nel machine learning e nella data science, Ke Shen è un ex studente della Columbia University ed ex Senior Data Scientist presso Walmart Labs. Grazie a una profonda competenza, riconosciuta dai suoi pari, in Python, R, Java e statistica, condivide insight collaudati sul passaggio di algoritmi AI complessi dalla teoria a un'architettura pronta per la produzione.
Topics
Middleware proxy per ScrapyWeb scraping con PythonRotazione dei proxy
Indice
Thunderbit · Agente AI per dati web

Estrai dati da qualsiasi pagina in 1 clic

Scelto da oltre 250.000 utenti
piano gratuito disponibile
Estrai dati usando l'AI
Trasferisci facilmente i dati su Fogli Google, Airtable o Notion
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week