Puppeteer es una biblioteca de Node que controla Chrome o Chromium (y Firefox) por programa. A diferencia de Playwright, no tiene un campo de usuario y contraseña del proxy al lanzar el navegador: la dirección del proxy se pasa como argumento de Chromium y la credencial se entrega después, página por página, con page.authenticate. Esta guía muestra la configuración con un proxy para todo el navegador, un proxy distinto por contexto, el caso de SOCKS5 y los errores más habituales.
Antes de empezar
En el panel, en Mis proxies, copia el host, el puerto HTTP, el usuario y la contraseña. Prueba la credencial antes con cURL, como explica la guía para probar el proxy: si cURL falla, el problema no está en Puppeteer.
Instala Puppeteer en tu proyecto. El paquete puppeteer descarga también una versión de Chrome compatible:
npm install puppeteer
No escribas la credencial en el código. Los ejemplos la leen de variables de entorno:
export PROXY_SERVER="http://p1.ejemplo.com:8000"
export PROXY_USER="tu-usuario"
export PROXY_PASS="tu-contrasena"
Los ejemplos usan módulos ES (import). Guarda el archivo con extensión .mjs o pon "type": "module" en el package.json.
Las dos piezas: --proxy-server y page.authenticate
| Qué | Dónde va | Ejemplo |
|---|---|---|
| Dirección del proxy | Argumento --proxy-server en puppeteer.launch |
--proxy-server=http://p1.ejemplo.com:8000 |
| Usuario y contraseña | page.authenticate({ username, password }) en cada página |
{ username: 'tu-usuario', password: 'tu-contrasena' } |
En --proxy-server va solo el esquema, el host y el puerto. No pongas http://usuario:contrasena@host:puerto: Chromium no usa esas credenciales y la conexión falla o se queda esperando la autenticación.
Proxy para todo el navegador
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch({
args: [`--proxy-server=${process.env.PROXY_SERVER}`],
});
const page = await browser.newPage();
await page.authenticate({
username: process.env.PROXY_USER,
password: process.env.PROXY_PASS,
});
await page.goto('https://api.ipify.org');
console.log('IP de salida:', await page.evaluate(() => document.body.innerText));
await browser.close();
Dos detalles que se olvidan con frecuencia:
authenticateva por página. Si abres otra página conbrowser.newPage(), llama de nuevo aauthenticateantes de navegar. Lo mismo con las ventanas emergentes que abra el sitio: captúralas con el eventopopupy autentícalas.- Llámalo antes de
goto. Si navegas primero, la primera petición llega al proxy sin credencial y recibes un 407.
La documentación de Puppeteer avisa de que authenticate activa por debajo la interceptación de peticiones, lo que puede afectar al rendimiento.
Un proxy por contexto
Un contexto de navegador es una sesión aislada dentro del mismo Chrome: cookies, almacenamiento y caché propios. En las versiones actuales de Puppeteer, browser.createBrowserContext acepta la opción proxyServer, así que cada contexto puede salir por una IP distinta sin abrir un navegador por cuenta. La credencial se sigue pasando con page.authenticate.
import puppeteer from 'puppeteer';
const cuentas = [
{ nombre: 'cliente-a', server: 'http://p1.ejemplo.com:8000', username: 'usuario-a', password: 'contrasena-a' },
{ nombre: 'cliente-b', server: 'http://p2.ejemplo.com:8000', username: 'usuario-b', password: 'contrasena-b' },
];
const browser = await puppeteer.launch();
for (const cuenta of cuentas) {
const context = await browser.createBrowserContext({ proxyServer: cuenta.server });
const page = await context.newPage();
await page.authenticate({ username: cuenta.username, password: cuenta.password });
await page.goto('https://httpbin.org/ip');
console.log(cuenta.nombre, await page.evaluate(() => document.body.innerText));
// ... aquí va el trabajo de la cuenta ...
await context.close();
}
await browser.close();
Los contextos creados así no guardan las cookies al cerrarse. Si una cuenta necesita mantener la sesión entre ejecuciones, la alternativa es un navegador por cuenta, cada uno con su --proxy-server y su propia carpeta de perfil en la opción userDataDir. En los dos casos, mantén fija la relación cuenta → proxy en un archivo de configuración, no en el código.
Un contexto aísla la sesión y la red, no la huella digital: todos los contextos comparten las características del mismo navegador. El porqué de este patrón, con Playwright como ejemplo, está en proxy por contexto en Playwright.
SOCKS5 con usuario y contraseña
Chromium acepta un proxy SOCKS5 en --proxy-server=socks5://host:puerto, pero no admite SOCKS5 con usuario y contraseña: no envía la credencial a un proxy SOCKS, y page.authenticate no resuelve este caso. Con un proxy de ProxyBox, que siempre se autentica por usuario y contraseña, hay dos caminos:
- Usar el puerto HTTP del mismo proxy. La IP de salida es la misma y el contenido de los sitios sigue cifrado por HTTPS. Es la opción recomendada; la diferencia entre protocolos está en HTTP, HTTPS y SOCKS5.
- Un reenviador local sin contraseña. Un pequeño proxy en tu máquina recibe la conexión del navegador en
127.0.0.1y la reenvía al proxy remoto ya con la credencial. El esquema conpproxyestá en la guía de proxy en Selenium.
Para el puerto HTTP, el paquete proxy-chain hace lo mismo desde Node y también sirve si authenticate te da problemas en algún flujo:
import puppeteer from 'puppeteer';
import { anonymizeProxy, closeAnonymizedProxy } from 'proxy-chain';
const remoto = `http://${process.env.PROXY_USER}:${process.env.PROXY_PASS}@p1.ejemplo.com:8000`;
const local = await anonymizeProxy(remoto); // devuelve algo como http://127.0.0.1:XXXXX
const browser = await puppeteer.launch({ args: [`--proxy-server=${local}`] });
const page = await browser.newPage();
await page.goto('https://api.ipify.org');
console.log('IP de salida:', await page.evaluate(() => document.body.innerText));
await browser.close();
await closeAnonymizedProxy(local, true);
Instalación: npm install proxy-chain. Aquí la credencial sí va en la URL, porque la lee proxy-chain, no Chromium. Si la contraseña tiene caracteres como @ o :, codifícala con encodeURIComponent.
Valida la salida
Antes de iniciar sesión en cualquier cuenta, confirma la IP de cada página o contexto, como hacen los ejemplos con https://api.ipify.org y https://httpbin.org/ip. Lo esperado:
- la IP que aparece es la que contrataste, no la de tu máquina;
- contextos distintos muestran IPs distintas;
- la misma cuenta muestra siempre la misma IP entre ejecuciones.
Para ver también país y proveedor, cambia la URL por https://ipinfo.io/json. Si prefieres comprobarlo a mano, abre Mi IP en un navegador configurado con el mismo proxy.
Errores comunes
net::ERR_PROXY_CONNECTION_FAILED. Chromium no llegó al proxy: host o puerto incorrectos, el puerto de otro protocolo o un cortafuegos en la máquina. Ver ERR_PROXY_CONNECTION_FAILED.
net::ERR_TUNNEL_CONNECTION_FAILED. El proxy respondió, pero no abrió el túnel hacia el sitio. Lo más habitual es una credencial incorrecta o que falte authenticate en esa página. Ver ERR_TUNNEL_CONNECTION_FAILED.
Respuesta 407 (Proxy Authentication Required). El proxy pide credencial y no la recibió o no es válida: authenticate llamado después de goto, una página nueva sin autenticar o un espacio de más al copiar la contraseña. Ver error 407.
Falla solo con SOCKS5. Estás usando socks5:// con un proxy que exige contraseña. Cambia al puerto HTTP o usa un reenviador local.
Todas las cuentas con la misma IP. El proxy solo está en --proxy-server del navegador. Para cuentas independientes, un contexto con su proxyServer o un navegador por cuenta.
El catálogo completo está en errores comunes de configuración.
Qué tipo de IP usar
- Cuentas con sesión iniciada: IPv4 dedicada, o ISP residencial si la plataforma es sensible a las IPs de datacenter. Una por contexto o por navegador.
- Recopilación sin sesión: no necesitas fijar una IP por contexto; cuántas IPs dimensionar se explica en automatización con proxy: cuántas IPs.
Lo que el proxy no resuelve
El proxy cambia la IP de salida. No cambia la huella digital del navegador automatizado, no resuelve CAPTCHAs y no hace que un sitio que prohíbe la automatización pase a permitirla. Respeta los términos de cada sitio y nuestra política de uso aceptable.
Para Playwright, mira proxy en Playwright; para Selenium, proxy en Selenium; y si dudas entre las tres herramientas, Selenium, Puppeteer o Playwright. Si todavía no tienes las IPs, mira el proxy para automatización.