# Guida ai Proxy di Python Requests: Sintassi, Autenticazione, Rotazione, Ritentativi

Il dizionario dei proxy è composto da tre righe di codice, eppure gli errori di proxy in Requests riempiono un decennio di discussioni su Stack Overflow. Ecco la configurazione completa — sintassi, autenticazione, variabili d'ambiente, rotazione, ritentativi e SOCKS5 — con i bordi taglienti etichettati.

Python Requests è ancora il client HTTP predefinito per scraping e automazione, e indirizzarlo a un proxy è un lavoro di tre righe: passa un dizionario di proxy e ogni richiesta esce dall'IP del proxy invece che dal tuo. Eppure 'python requests proxy non funzionante' è rimasto una delle ricerche principali per oltre un decennio — la domanda originale su Stack Overflow riguardo al dizionario dei proxy risale al 2011, la risposta più votata ha oltre 480 voti, ed è stata ancora modificata a gennaio 2026. La sintassi ha bordi taglienti: uno schema mancante solleva un'eccezione, lo schema sbagliato all'interno della chiave https provoca errori SSL, e le variabili d'ambiente sovrascrivono silenziosamente il codice. Questa guida ai proxy di Python Requests copre tutto: sintassi, autenticazione, variabili d'ambiente, rotazione, ritentativi, SOCKS5 e gli errori che incontrerai realmente.

## Il dizionario dei proxy: sintassi del proxy di Python Requests

L'argomento `proxies` mappa un protocollo a un URL di proxy. Due chiavi coprono lo scraping normale — una per i target HTTP semplici, una per i target HTTPS — e di solito entrambe puntano allo stesso proxy:

```python
import requests

proxies = {
    "http": "http://USER:PASS@residentialpremium.quantumproxies.io:8080",
    "https": "http://USER:PASS@residentialpremium.quantumproxies.io:8080",
}

r = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=(5, 30))
print(r.json())  # {'origin': '<proxy exit IP>'}
```

Tre regole prevengono il 90% dei fallimenti di configurazione:

- **Lo schema è obbligatorio.** Dalla versione 2.0.0 di Requests, un URL di proxy senza `http://` solleva `MissingSchema`. Le stringhe `ip:port` nude funzionavano nella versione 1.x e si sono rotte ovunque quando è arrivata la 2.0.
- **Usa `http://` all'interno della chiave `https`.** La chiave nomina il protocollo di destinazione; il valore nomina come raggiungi il proxy. I proxy accettano HTTP semplice e tunnel TLS tramite una richiesta CONNECT. Scrivere `https://` lì è la causa classica di `SSLError: UNEXPECTED_EOF_WHILE_READING`.
- **Le chiavi possono indirizzare host specifici.** Una chiave come `https://api.example.com` instrada solo quell'host attraverso un dato proxy — utile per inviare un dominio difficile attraverso IP residenziali mentre tutto il resto va diretto.

## Autenticazione del proxy: username e password

I proxy autenticati usano l'autenticazione HTTP Basic incorporata nell'URL: `http://USER:PASS@host:port`. Se la password contiene `@`, `:` o `/`, codificala prima con `urllib.parse.quote(password, safe="")` — i caratteri speciali non codificati dividono l'URL nel posto sbagliato e producono errori di autenticazione che sembrano proxy morti. Una risposta `407 Proxy Authentication Required` significa che il proxy stesso ti ha rifiutato: credenziali errate, o un piano di whitelist IP chiamato da un indirizzo non registrato. Entrambi i casi sono analizzati nella [nostra guida alla risoluzione dei problemi 407](https://quantumproxies.io/blog/fix-407-proxy-authentication-required). Per qualsiasi cosa oltre uno script una tantum, allega i proxy a una `Session` — ottieni il pooling delle connessioni, la persistenza dei cookie e un unico posto per configurare tutto:

```python
import requests

session = requests.Session()
session.proxies = {
    "http": "http://USER:PASS@residentialpremium.quantumproxies.io:8080",
    "https": "http://USER:PASS@residentialpremium.quantumproxies.io:8080",
}
session.headers.update({"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"})

r = session.get("https://httpbin.org/ip", timeout=(5, 30))
print(r.status_code, r.json())
```

## Variabili d'ambiente e trust_env

Requests legge anche le impostazioni del proxy dall'ambiente — le stesse variabili che curl e la maggior parte degli strumenti Unix rispettano: `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY` e `NO_PROXY` (un elenco separato da virgole di host da escludere, ad esempio `localhost,127.0.0.1,.internal`). Questo è il modo più pulito per proxy un libreria di terze parti che utilizza Requests senza toccare il suo codice. La precedenza segue il principio esplicito-batte-implicito: un argomento `proxies=` nella chiamata vince, poi `session.proxies`, poi l'ambiente. Due strumenti correlati vale la pena conoscere: `session.trust_env = False` disattiva tutte le ricerche nell'ambiente — la soluzione quando una variabile di proxy aziendale dirotta il tuo scraper — e `urllib.request.getproxies()` restituisce le impostazioni di proxy a livello di sistema operativo (inclusi i sistemi macOS e Windows) esattamente nella forma di dizionario che Requests si aspetta.

![Lo stesso dizionario proxies a due chiavi manda tre iterazioni del ciclo attraverso il tunnel CONNECT di un gateway rotante, e httpbin.org/ip riporta ogni volta un'origine diversa: IP di uscita A, B e C. La scheda: il dizionario sceglie il percorso, il tunnel porta il TLS fino al target e il gateway fornisce un nuovo IP di uscita a ogni chiamata.](https://res.cloudinary.com/dmqliab0t/image/upload/f_auto,q_auto,w_1200/v1785335141/blog/generated/qp-b9-001-diag1.png)
*Il dizionario sceglie il percorso, il gateway fornisce l'IP di uscita. Con la rotazione per richiesta, le stesse due righe di configurazione producono un nuovo IP ad ogni chiamata.*

## Rotazione: un gateway batte una lista di proxy

La ricetta tradizionale di rotazione — caricare una lista di IP, `random.choice()` per richiesta, eliminare quelli morti — è un meccanismo che non devi più costruire. Un gateway rotante lo fa lato server: configuri un endpoint e il fornitore assegna un nuovo IP di uscita dal pool ad ogni richiesta. Attraverso [proxy residenziali rotanti](https://quantumproxies.io/rotating-proxies) quel pool è composto da oltre 90 milioni di IP domestici in più di 200 paesi, quindi mille richieste sembrano mille visitatori diversi senza una sola riga di logica di rotazione:

```python
import requests

proxies = {
    "http": "http://USER:PASS@residentialpremium.quantumproxies.io:8080",
    "https": "http://USER:PASS@residentialpremium.quantumproxies.io:8080",
}

for _ in range(3):
    r = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=(5, 30))
    print(r.json()["origin"])  # a different exit IP on each iteration
```

Quando un flusso copre diverse richieste — login, aggiungi al carrello, checkout — la rotazione per richiesta interrompe la sessione. Le sessioni sticky risolvono questo: un parametro di sessione nel nome utente del proxy fissa un IP di uscita per una finestra impostata, poi ruota. Stesso endpoint, un cambio di stringa. Se stai scalando oltre semplici loop, [Python asincrono con httpx o aiohttp](https://quantumproxies.io/blog/python-async-scraping-httpx-aiohttp-proxies) moltiplica la capacità, e il [sistema di middleware di Scrapy](https://quantumproxies.io/blog/scrapy-rotating-proxy-middleware) ti offre rotazione, ritentativi e gestione dei ban come configurazione del framework.

## Ritentativi e timeout che sopravvivono a uscite difettose

Anche i pool premium servono occasionalmente uscite lente o morenti, quindi il codice di produzione ha bisogno di due protezioni: un timeout su ogni richiesta (Requests di default attende all'infinito) e ritentativi automatici con backoff. Il timeout prende una tupla `(connect, read)` — fallisce rapidamente su proxy irraggiungibili, consente letture di pagina più lente. I ritentativi si montano a livello di trasporto tramite urllib3:

```python
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

retry = Retry(
    total=4,
    backoff_factor=1,  # exponential backoff between attempts
    status_forcelist=[429, 500, 502, 503, 504],
    allowed_methods=["GET", "HEAD"],
)

session = requests.Session()
session.mount("http://", HTTPAdapter(max_retries=retry))
session.mount("https://", HTTPAdapter(max_retries=retry))
session.proxies = {
    "http": "http://USER:PASS@residentialpremium.quantumproxies.io:8080",
    "https": "http://USER:PASS@residentialpremium.quantumproxies.io:8080",
}

r = session.get("https://httpbin.org/ip", timeout=(5, 30))
```

Con un gateway rotante questa combinazione è silenziosamente potente: ogni ritentativo viaggia automaticamente attraverso un diverso IP di uscita, quindi un indirizzo instabile non può mai far fallire una richiesta quattro volte di seguito.

## Proxy SOCKS5 con Requests

Il supporto SOCKS è un extra: installalo con `pip install requests[socks]`. Poi la sintassi del dizionario è identica — cambia solo lo schema. Preferisci `socks5h://` a `socks5://`: la `h` spinge la risoluzione DNS al proxy, che impedisce perdite DNS dalla tua rete reale e risolve nomi host geo-restritti dalla posizione dell'uscita. Ogni piano QuantumProxies espone sia proxy HTTP che [proxy SOCKS5](https://quantumproxies.io/socks5-proxies) sullo stesso gateway, quindi cambiare protocollo è uno scambio di schema, non un nuovo acquisto:

```python
proxies = {
    "http": "socks5h://USER:PASS@residentialpremium.quantumproxies.io:1080",
    "https": "socks5h://USER:PASS@residentialpremium.quantumproxies.io:1080",
}
```

![Cinque errori proxy con Python Requests e cosa provoca ciascuno: uno schema mancante genera MissingSchema, https:// nella chiave https dà un SSLError, una password non codificata riceve un 407, SOCKS richiede l'extra requestssocks e l'assenza di timeout fa attendere all'infinito. La scheda: tre regole prevengono il 90% degli errori di configurazione.](https://res.cloudinary.com/dmqliab0t/image/upload/f_auto,q_auto,w_1200/v1785335141/blog/generated/qp-b9-001-diag2.png)
*Cinque errori causano la maggior parte dei fallimenti: schema mancante, https:// nella chiave https, password non codificate, extra SOCKS mancanti e nessun timeout.*

## Errori comuni di proxy di Python Requests, decodificati

- **MissingSchema** — l'URL del proxy manca di `http://`. Obbligatorio dalla versione 2.0.0 di Requests.
- **ProxyError: Cannot connect to proxy** — host o porta errati, o un proxy morto. Verifica l'endpoint con curl prima di incolpare il tuo codice.
- **SSLError / UNEXPECTED_EOF_WHILE_READING** — di solito `https://` all'interno della chiave `https`. Imposta lo schema del valore su `http://`.
- **407 Proxy Authentication Required** — credenziali errate, caratteri speciali non codificati nella password, o un IP sorgente non in whitelist.
- **ConnectTimeout / ReadTimeout** — uscita lenta o target lento. Imposta `timeout=(5, 30)` e lascia che i ritentativi ruotino su un nuovo IP.
- **Il proxy funziona in curl, fallisce in Python** — una variabile d'ambiente sta sovrascrivendo il tuo dizionario. Stampa `session.proxies` e prova `trust_env = False`.

Per un'analisi più approfondita delle tracce dello stack e delle loro cause principali, vedi [debugging ProxyError, SSLError e ConnectTimeout in Requests](https://quantumproxies.io/blog/python-requests-proxyerror-fix).

## Domande frequenti

### Come uso un proxy con Python Requests?

Passa un dizionario `proxies` con chiavi `http` e `https` a qualsiasi metodo di richiesta: `requests.get(url, proxies={...})`. Ogni valore è un URL di proxy completo incluso lo schema, e le credenziali sono incorporate come `http://user:pass@host:port`. Allega lo stesso dizionario a una `Session` per applicarlo automaticamente a ogni richiesta.

### Perché il mio proxy di Python Requests non funziona?

Controlla i quattro sospetti usuali in ordine: uno schema `http://` mancante nell'URL del proxy, `https://` usato all'interno della chiave `https`, caratteri speciali nella password che non sono stati codificati nell'URL, e variabili d'ambiente che sovrascrivono il tuo codice. Testa le stesse credenziali con curl — se curl ha successo, il problema è nel tuo dizionario.

### Python Requests supporta i proxy SOCKS5?

Sì, dopo aver installato la dipendenza extra con `pip install requests[socks]`. Usa lo schema `socks5h://` nel tuo dizionario dei proxy in modo che la risoluzione DNS avvenga sul lato proxy — lo schema semplice `socks5://` risolve i nomi host localmente, il che perde le query DNS e può interrompere lo scraping geo-targeted.

### Come imposto un proxy con le variabili d'ambiente?

Esporta `HTTP_PROXY` e `HTTPS_PROXY` con l'URL completo del proxy, e facoltativamente `NO_PROXY` per gli host da escludere. Requests li rileva automaticamente, il che proxy anche le librerie di terze parti costruite su Requests. Per far sì che il tuo codice ignori completamente l'ambiente, imposta `session.trust_env = False`.

Questo è l'intero toolkit: un dizionario a due chiavi, credenziali nell'URL, ritentativi montati una volta, e rotazione gestita dal gateway invece che dal tuo codice. L'unica cosa che nessuna sintassi può risolvere è la qualità dell'IP — un proxy datacenter perfettamente configurato viene ancora bloccato dove un'uscita residenziale passa senza problemi. Abbina codice pulito a IP puliti e Requests gestirà carichi sorprendentemente grandi.

[Ottieni proxy residenziali che funzionano al primo tentativo](https://quantumproxies.io/residential-proxies)
