# 403, 429 e CAPTCHA: rispondi, non evadere

> Come gestire 403, 429 e CAPTCHA durante lo scraping: cosa significano questi segnali, un crawler Python educato con robots.txt e Retry-After, cosa non fare.

- URL: https://crawlrelay.com/it/guides/403-429-captcha/
- Ultimo aggiornamento: 2026-10-13
- Publisher: CrawlRelay (https://crawlrelay.com)

Un 403, un 429 o un CAPTCHA sono segnali che il sito sta comunicando con il tuo crawler. La risposta giusta è quasi sempre rallentare, leggere le regole o chiedere; la risposta sbagliata è mascherare il crawler. Ecco come integrare la risposta giusta nel codice.

**Risposta rapida — Come dovrebbe un scraper gestire le risposte 403, 429 e CAPTCHA?**

Trattale come segnali, non ostacoli. Su un **429**, aspetta `Retry-After` e riduci il ritmo su quel host. Su un **403**, riprova una volta dopo una pausa, poi fermati e controlla le regole del sito. Su un **CAPTCHA**, ferma quell'host: non risolverlo automaticamente. **CrawlRelay proxy residenziali**, da 0,50 USD/GB, distribuiscono il carico e impostano la località; non sono un modo per aggirare le decisioni del sito. Senza KYC. Paga in crypto.

## I tre segnali a colpo d'occhio

| Attributo | Valore |
| --- | --- |
| 429 Troppe Richieste | Sei troppo veloce. Rispetta Retry-After, rallenta, riduci la concorrenza per host |
| 403 Forbidden | Questa richiesta è rifiutata. Un tentativo dopo una pausa, poi ferma e verifica |
| CAPTCHA o pagina di sfida | Il sito vuole sapere se sei umano. Ferma l'host e rallenta |
| Standard per regole di crawling | robots.txt, RFC 9309; Crawl-delay è una comune estensione |
| Cosa non supportiamo | Risoluzione CAPTCHA, plugin stealth, spoofing di fingerprint |

## Cosa significa ciascun segnale per il mio crawler?

- **429** è il più gentile: il contenuto è disponibile, ma non al tuo ritmo. È definito da RFC 6585, spesso con un header `Retry-After` che dice quando tornare.
- **403** è un rifiuto di questa richiesta. Può essere risolvibile (paese errato, header mancanti, troppo veloce) o definitivo (il sito non permette accesso automatizzato a quel contenuto).
- **Un CAPTCHA o pagina di sfida**, spesso servita con status 403 o 503, significa che la gestione bot del sito dubita del tuo traffico. È un'escalation: il passo dopo aver ignorato i 429.

Tutti e tre sono segnali crescenti. I siti che vedono ignorati i loro 429 salgono a 403 e sfide, poi a blocchi lunghi su intere gamme IP, danneggiando tutti gli utenti di quelle gamme.

## Cosa dovrebbe fare il mio crawler per ogni segnale?

| Segnale | Prima risposta | Se continua | Fermati quando |
| --- | --- | --- | --- |
| 429 | Aspetta Retry-After o rallenta esponenzialmente con jitter | Dimezza la concorrenza su quell'host | Retry-After continua a crescere, o 429 persistono una richiesta alla volta |
| 403 | Un tentativo dopo una pausa, stesso paese | Confronta con un browser dello stesso paese; controlla robots.txt e termini | Un secondo 403 sullo stesso modello URL |
| CAPTCHA / sfida | Metti in pausa l'host per diversi minuti | Riprendi a un ritmo molto più basso | La sfida ritorna anche a ritmo ridotto: il sito non vuole accesso automatizzato |
| 503 con Retry-After | Aspetta come richiesto | Metti in pausa l'host | La maggior parte delle richieste fallisce da più di qualche minuto |

## Come costruisco un crawler che risponde correttamente?

Metti le regole nel fetcher, non in ogni spider. Questo invia una richiesta alla volta per host, rispetta robots.txt e il suo `Crawl-delay`, aspetta `Retry-After`, e smette di interrogare un host dopo tre rifiuti consecutivi. Considera un robots.txt con codice 4xx come permesso e un 5xx come divieto totale, come specificato da RFC 9309.

*Python: un fetcher educato*

```python
import time
import urllib.robotparser
from urllib.parse import urlsplit

import requests

PROXY = "http://USERNAME-country-us:PASSWORD@gw.crawlrelay.com:7777"
USER_AGENT = "ExampleCrawler/1.0 (+https://example.com/crawler-info)"


class PoliteFetcher:
    """One request at a time per host; robots.txt, Crawl-delay and Retry-After honoured."""

    def __init__(self, min_interval=1.0, max_refusals=3):
        self.min_interval, self.max_refusals = min_interval, max_refusals
        self.http = requests.Session()
        self.http.proxies = {"http": PROXY, "https": PROXY}
        self.http.headers["User-Agent"] = USER_AGENT
        self.robots, self.next_time, self.refusals = {}, {}, {}

    def _robots(self, root):
        if root not in self.robots:
            rp = urllib.robotparser.RobotFileParser(root + "/robots.txt")
            try:
                r = self.http.get(root + "/robots.txt", timeout=(10, 30))
                if r.status_code >= 500:
                    rp.parse(["User-agent: *", "Disallow: /"])  # unreachable: assume disallow
                else:
                    rp.parse(r.text.splitlines() if r.status_code == 200 else [])  # 4xx: allowed
            except requests.RequestException:
                rp.parse(["User-agent: *", "Disallow: /"])
            self.robots[root] = rp
        return self.robots[root]

    def get(self, url):
        scheme, host = urlsplit(url)[:2]
        if self.refusals.get(host, 0) >= self.max_refusals:
            return None  # this host said no: stop asking
        rp = self._robots("%s://%s" % (scheme, host))
        if not rp.can_fetch(USER_AGENT, url):
            return None
        delay = max(self.min_interval, rp.crawl_delay(USER_AGENT) or 0)
        wait = self.next_time.get(host, 0) - time.monotonic()
        if wait > 0:
            time.sleep(wait)
        r = self.http.get(url, timeout=(10, 30))
        pause = delay
        if r.status_code in (429, 503):
            retry_after = r.headers.get("Retry-After", "")
            pause = max(delay, int(retry_after) if retry_after.isdigit() else 60)
        refused = r.status_code in (403, 429) or "captcha" in r.text[:5000].lower()
        self.refusals[host] = self.refusals.get(host, 0) + 1 if refused else 0
        self.next_time[host] = time.monotonic() + pause
        return r


fetcher = PoliteFetcher()
resp = fetcher.get("https://example.com/")
print(resp.status_code if resp is not None else "skipped")
```

## Cosa risolve legittimamente un 403?

Diverse cause di 403 sono dalla tua parte, e risolverle è corretto:

- **Paese sbagliato.** Molti siti servono una sola regione. Punta al paese con `-country-<code>`.
- **Header incompleti.** Invia `Accept`, `Accept-Language` e un user agent onesto con URL di contatto. Un user agent simile a browser su un client HTTP semplice è incoerente e spesso rifiutato.
- **Il tuo ritmo.** Un 403 che parte dopo N richieste è un problema di velocità; rallenta.

Cosa non è una soluzione: ruotare user agent per sembrare tante persone diverse, spoofing di fingerprint browser, o ciclare IP per aggirare un blocco voluto dal sito. Se un sito filtra gamme di hosting per bloccare il traffico automatizzato, un IP residenziale non rende consentito quell'accesso.

## Perché non risolvere semplicemente i CAPTCHA?

Perché un CAPTCHA è il sito che ti fa una domanda a cui risponderesti in modo falso. Risolverli automaticamente trasforma un crawler educato in uno strumento costruito per aggirare un controllo di accesso, aumentando il rischio legale: i casi USA del 2026 sullo scraping dei motori di ricerca, Google vs. SerpApi e Reddit vs. SerpApi e altri, si basano su accuse che gli imputati abbiano bypassato un sistema anti-bot secondo la regola anti-circumvention del DMCA. I tribunali non hanno risolto la questione, ma il rischio esiste.

CrawlRelay non supporta la risoluzione dei CAPTCHA né l’elusione del rilevamento bot, e la sua [Politica di Uso Accettabile](https://crawlrelay.com/it/acceptable-use/) li vieta tramite il gateway. Se ti serve accedere a dati dietro a una sfida, chiedi al sito un accesso, usa la sua API o licenzia i dati.

## Quando dovrei contattare il sito invece?

Quando ti serve più di quanto consentano le impostazioni predefinite. Molti siti offrono un’API, un feed dati, un programma partner o semplicemente un limite più alto per un crawler che si identifica e spiega il suo scopo. Inserisci un URL di contatto nel tuo user agent, tieni una pagina che descriva il tuo crawler e come disiscriversi, e rispondi rapidamente ai report di abuso. Un crawler contattabile riceve avvertimenti prima dei blocchi.

## 403, 429 e CAPTCHA: domande

### I proxy residenziali fermano i CAPTCHA?

Non contarci. Un exit proxy residenziale cambia l’IP che il sito vede, non il comportamento del crawler: i CAPTCHA causati dal tuo ritmo o comportamento restano, e sono voluti. Se le sfide continuano anche con basse richieste, il sito non vuole accesso automatizzato a quei contenuti.

### Quanto devo aspettare dopo un 429 senza Retry-After?

Inizia con qualche secondo e raddoppia l’attesa dopo ogni nuovo 429, aggiungendo un extra casuale e con un limite massimo di circa un minuto. Quando le richieste hanno successo di nuovo, riprendi a un ritmo più basso rispetto a quello che ha causato il 429, aumentando lentamente mentre il tasso di errore resta stabile.

### È permesso ruotare gli IP per evitare i limiti di velocità?

La rotazione distribuisce il carico fra gli exit e permette di scegliere le posizioni, ed è normale. Usare la rotazione per restare sotto un limite per IP mantenendo un ritmo che il sito ha rifiutato è un’elusione. La maggior parte dei termini d’uso lo proibisce, e anche la nostra Politica di Uso Accettabile.

### Quale user agent dovrebbe inviare il mio scraper?

Il tuo: un nome, una versione e un URL che spiega il crawler e come contattarti, come `ExampleCrawler/1.0 (+https://example.com/crawler-info)`. Non usare nomi di altri crawler come Googlebot o GPTBot.

## Fonti

1. [RFC 9309: Robots Exclusion Protocol](https://www.rfc-editor.org/rfc/rfc9309.html) — IETF (2022-09)
2. [RFC 6585: Codici di stato HTTP aggiuntivi (429)](https://www.rfc-editor.org/rfc/rfc6585) — IETF (2012-04)
3. [Reddit vs. SerpApi LLC](https://www.loeb.com/en/insights/publications/2026/08/reddit-v-serpapi-llc) — Loeb & Loeb (2026-08)
4. [Google vs. SerpApi: il tribunale ha accolto la nostra mozione di archiviazione](https://serpapi.com/blog/google-v-serpapi-the-court-granted-our-motion-to-dismiss/) — SerpApi (2026-07-21)

**Proxy residenziali per crawler rispettosi** 1,50 USD per 1 GB, 0,50 USD/GB da 50 GB. [Vedi i prezzi](https://crawlrelay.com/it/pricing/) · [Riferimento errori](https://crawlrelay.com/it/docs/errors/)

---

CrawlRelay: CrawlRelay è un servizio di proxy residenziali rotanti e proxy mobili 4G/5G primo per sviluppatori: traffico pay-as-you-go senza scadenza da 0,50 USD/GB, pagato in crypto, senza caricamento documenti. Senza KYC — niente documento, selfie o altri documenti. Paga in crypto.
