Configurazione Proxy Puppeteer: Flag, Autenticazione, Rotazione e Realtà
Il flag di avvio è semplice; il 407 che segue è dove la maggior parte delle configurazioni proxy di Puppeteer fallisce. Ecco il modello completo — page.authenticate, rotazione del contesto, proxy-chain — e la verità sui proxy per pagina e il rilevamento headless.
La configurazione del proxy Puppeteer inizia con un flag di avvio e, per la maggior parte delle persone, si ferma un passo dopo contro un muro: il proxy risponde 407 Proxy Authentication Required, perché --proxy-server non può trasportare credenziali. La soluzione è integrata — page.authenticate() — ma intorno si trova un campo minato di consigli parzialmente funzionanti: pacchetti npm che reindirizzano silenziosamente il tuo traffico attraverso Node.js, schemi SOCKS che Chromium non autenticherà, e un bypass localhost che fa sembrare morti i proxy funzionanti. Questa guida illustra la configurazione che regge in produzione: flag, autenticazione, rotazione con contesti del browser, proxy-chain per i casi difficili, e una sezione onesta sul rilevamento headless.
Configurazione proxy Puppeteer: il modello base
Il proxy è un argomento di avvio di Chromium, quindi si applica a tutto il browser. Le credenziali passano attraverso page.authenticate(), che risponde alla sfida 407 del proxy tramite il protocollo DevTools — chiamalo prima di qualsiasi navigazione:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
args: ['--proxy-server=http://gate.quantumproxies.io:PORT'],
});
const page = await browser.newPage();
await page.authenticate({ username: 'USER', password: 'PASS' });
await page.goto('https://httpbin.org/ip', { waitUntil: 'domcontentloaded' });
console.log(await page.evaluate(() => document.body.innerText)); // exit IP
await browser.close();
})();
Quattro dettagli risparmiano ore di debugging:
- Costruisci il flag con un template literal o concatenazione, non con semplici virgolette. Un classico bug di Stack Overflow:
"--proxy-server =..."tra doppi apici con un segnaposto di interpolazione non sostituisce mai la variabile — e lo spazio extra rompe anche l'analisi. - Includi lo schema.
--proxy-server=socks5://host:portper SOCKS, altrimenti Chromium assume HTTP. - Non incorporare
user:pass@nel flag. Chromium lo ignora; solopage.authenticate()(o il whitelisting IP) autentica. - Localhost bypassa il proxy. Chromium salta i proxy per gli URL di loopback — un enigma documentato nel problema #3711 di Puppeteer. Aggiungi
--proxy-bypass-list=<-loopback>se hai davvero bisogno di proxy per il traffico locale; altrimenti testa semplicemente contro un URL esterno.

Rotazione dei proxy con contesti del browser
Rilanciare Chrome per IP costa secondi e centinaia di MB ogni volta. I contesti del browser risolvono questo problema: dal Puppeteer v22 l'API è browser.createBrowserContext() (sostituendo la vecchia variante in incognito), accetta un'opzione proxyServer, e un contesto viene creato in millisecondi con i propri cookie e storage:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const jobs = ['https://example.com/a', 'https://example.com/b'];
for (const url of jobs) {
const context = await browser.createBrowserContext({
proxyServer: 'http://gate.quantumproxies.io:PORT',
});
const page = await context.newPage();
await page.authenticate({ username: 'USER', password: 'PASS' });
try {
await page.goto(url, { timeout: 30000 });
// ...extract...
} finally {
await context.close();
}
}
await browser.close();
})();
Contro un gateway rotante, ogni contesto esce naturalmente da un indirizzo diverso nel pool — con proxy residenziali rotanti che sono oltre 90M di IP in più di 200 paesi dietro un unico hostname, e un parametro username di sessione fissa un'uscita quando un flusso multi-pagina necessita di continuità. Questa è la stessa architettura contesto-per-lavoro che raccomandiamo per Playwright; Puppeteer semplicemente esplicita il passaggio di autenticazione.
Due abitudini mantengono la rotazione onesta. Registra l'IP di uscita per contesto durante lo sviluppo — colpisci un endpoint IP-echo all'inizio del contesto e memorizzalo con le tue righe di scraping, così quando un target inizia a bloccarti puoi capire se è un'uscita o un'impronta digitale il colpevole. E limita la tua concorrenza: ogni contesto è economico, ma ogni pagina aperta mantiene ancora memoria del renderer, quindi un semaforo attorno alla creazione del contesto batte un ciclo illimitato la prima volta che una lista di lavori cresce a migliaia di URL.
proxy-chain: il ponte locale per autenticazioni difficili
Due casi rompono il modello flag-più-autenticazione: SOCKS5 autenticato (Chromium non ha supporto per le credenziali SOCKS) e strumenti che accettano solo un URL proxy nudo senza passaggio di autenticazione. Il pacchetto npm proxy-chain risolve entrambi avviando un proxy locale senza credenziali che inoltra al tuo upstream autenticato:
const puppeteer = require('puppeteer');
const proxyChain = require('proxy-chain');
(async () => {
const upstream = 'http://USER:PASS@gate.quantumproxies.io:PORT';
const localUrl = await proxyChain.anonymizeProxy(upstream);
// localUrl is something like http://127.0.0.1:54321 — no credentials needed
const browser = await puppeteer.launch({
args: ['--proxy-server=' + localUrl],
});
const page = await browser.newPage();
await page.goto('https://httpbin.org/ip');
await browser.close();
await proxyChain.closeAnonymizedProxy(localUrl, true);
})();
Fondamentale, le richieste della pagina partono ancora da Chrome stesso — proxy-chain inoltra solo byte, quindi la tua impronta digitale TLS rimane quella di un vero browser. Questa distinzione è la prossima sezione.
Proxy per pagina: la risposta onesta
Puppeteer non ha un proxy per pagina nativo, e le soluzioni più popolari — puppeteer-page-proxy, puppeteer-proxy — intercettano ogni richiesta e la rilanciano da Node.js con una libreria HTTP, quindi restituiscono la risposta al browser. Tre conseguenze: il target ora vede una stretta di mano TLS di Node invece di quella di Chrome, che JA3/JA4 fingerprinting segnala istantaneamente su siti protetti; ogni richiesta paga un viaggio di andata e ritorno attraverso Node; e entrambi i pacchetti sono effettivamente non mantenuti, con installazione rotta fuori dalla scatola secondo i loro stessi tracker di problemi. Se hai bisogno di IP diversi per pagine diverse, usa un contesto per proxy come sopra — stesso effetto, traffico reale di Chrome, API supportata.

Realtà del rilevamento headless
Un proxy risolve il livello di rete; non può rendere invisibile Chrome headless. La vecchia modalità headless si annunciava con un token User-Agent HeadlessChrome; il nuovo headless (predefinito di Puppeteer dalla v22) condivide l'architettura del browser reale e chiude gran parte di quel divario, ma i rilevatori sondano ancora navigator.webdriver, effetti collaterali CDP e peculiarità di rendering — e i plugin stealth correggono i controlli di ieri, non quelli di domani. Ordina le tue correzioni per ritorno sull'impegno: un IP residenziale pulito [](https://quantumproxies.io/residential-proxies) prima, perché la reputazione è il filtro più economico per i siti da eseguire e quello che il tuo codice non può falsificare; intestazioni e ritmo sensati in secondo luogo (la nostra guida su evitare i CAPTCHA copre i segnali di attivazione); e quando un target rinforzato vince ancora, instrada quel dominio attraverso un Scraper API che gestisce rendering, impronte digitali e tentativi e restituisce HTML, markdown o JSON puliti — una chiamata HTTP invece di una flotta di browser patchati.
Domande frequenti
Come autentico un proxy in Puppeteer?
Imposta l'indirizzo con args: ['--proxy-server=http://host:port'] all'avvio, quindi chiama await page.authenticate({ username, password }) su ogni pagina prima di navigare. Le credenziali incorporate nell'URL del flag sono ignorate da Chromium. Per SOCKS5 con autenticazione, usa proxy-chain come ponte locale, poiché Chromium non può inviare credenziali SOCKS.
Puppeteer può usare un proxy diverso per pagina?
Non nativamente — il flag di avvio è a livello di browser. L'equivalente supportato è un contesto del browser per proxy tramite browser.createBrowserContext({ proxyServer }), con pagine all'interno di ogni contesto. I pacchetti che promettono veri proxy per pagina reindirizzano le richieste attraverso Node.js, cambiando la tua impronta digitale TLS e venendo segnalati dai sistemi anti-bot seri.
Puppeteer supporta i proxy SOCKS5?
Sì per gli endpoint non autenticati: passa --proxy-server=socks5://host:port. SOCKS5 autenticato fallisce perché Chromium non ha un meccanismo di credenziali SOCKS e page.authenticate() risponde solo alle sfide HTTP 407. Soluzioni alternative: usa la porta HTTP del gateway con autenticazione, inserisci nella whitelist il tuo IP, o esegui proxy-chain come ponte locale.
Come ruoto i proxy in Puppeteer?
Crea un nuovo contesto del browser per lavoro con createBrowserContext({ proxyServer }) e puntalo a un gateway rotante — ogni contesto esce quindi automaticamente da un nuovo IP, senza dover gestire una lista di proxy. Rilanciare l'intero browser per IP funziona anche ma costa secondi e centinaia di MB di RAM per rotazione.
Perché il mio proxy Puppeteer non funziona per localhost?
Chromium bypassa i proxy per gli indirizzi di loopback per design, quindi le richieste a localhost o 127.0.0.1 vanno dirette — comportamento che ha sorpreso abbastanza persone da diventare un problema numerato di Puppeteer. Aggiungi --proxy-bypass-list=<-loopback> per forzare il proxy, o semplicemente verifica il tuo proxy contro un endpoint IP-echo esterno.
Il modello durevole è piccolo: flag per l'indirizzo, page.authenticate() per le credenziali, contesti per la rotazione, proxy-chain per i casi particolari — e scetticismo per qualsiasi pacchetto che sposta le tue richieste fuori dal browser. Dai a quello stack uscite residenziali pulite e Puppeteer rimane noioso, che è il più grande complimento che l'infrastruttura possa ricevere.