Playwright es una de las herramientas más poderosas para la automatización de navegadores, pruebas sin cabeza y scraping de datos. Pero sin un proxy correctamente configurado, tu script rápidamente será bloqueado por IP: los sitios han aprendido a reconocer las solicitudes automatizadas y a bloquearlas. En esta guía, analizaremos todas las formas de conectar un proxy en Playwright, desde la configuración básica hasta la rotación de IP y la elusión de Cloudflare.
¿Por qué usar un proxy en Playwright y cuándo es imprescindible?
Playwright ejecuta un navegador real (Chromium, Firefox o WebKit) en segundo plano — eso es lo que se conoce como sin cabeza. Desde el punto de vista del sitio, pareces un usuario normal, pero solo hasta cierto punto. Tan pronto como desde una IP comienzan a llegar cientos de solicitudes por hora, los algoritmos de protección reaccionan de inmediato: CAPTCHA, bloqueo temporal, prohibición total.
Aquí hay escenarios específicos en los que un proxy es obligatorio:
- Scraping de marketplaces — Wildberries, Ozon, Avito, Yandex.Market bloquean scripts después de 50–100 solicitudes desde una IP.
- Monitoreo de precios de competidores — si ejecutas una verificación cada 15 minutos, sin cambiar de IP recibirás un bloqueo en unas pocas horas.
- Pruebas de geolocalización — necesitas verificar cómo se ve el sitio para usuarios de Alemania, EE. UU. o Kazajistán.
- Relleno de formularios y registro de cuentas — las plataformas vinculan cuentas a IP y bloquean registros masivos.
- Monitoreo SEO — la recopilación de posiciones de Google y Yandex requiere un cambio constante de IP, de lo contrario, el motor de búsqueda mostrará CAPTCHA.
- Pruebas de funciones A/B — algunas características solo están disponibles para usuarios de ciertos países o regiones.
Es importante entender: Playwright por sí solo no te hace anónimo. Sin un proxy, todas las solicitudes provienen de tu dirección IP real. Agregar un proxy es el primer y más importante paso hacia un funcionamiento estable de cualquier script automatizado.
💡 Importante saber
Playwright admite proxies a nivel de todo el navegador, contexto separado (BrowserContext) e incluso página individual. Esto proporciona flexibilidad: diferentes páginas pueden operar a través de diferentes IP simultáneamente.
Qué tipo de proxy elegir para la automatización sin cabeza
No todos los proxies son igualmente adecuados para Playwright. La elección depende de la tarea: qué estás scrapeando, cuán agresiva es la protección del sitio y cuántas solicitudes planeas realizar.
| Tipo de proxy | Nivel de confianza | Velocidad | Adecuado para |
|---|---|---|---|
| Centro de datos | Bajo | Muy alta | Scraping sin protección estricta, pruebas |
| Residenciales | Alto | Media | Sitios con Cloudflare, marketplaces, redes sociales |
| Móviles | Máximo | Media | Facebook, TikTok, Instagram, estrictas protecciones contra bots |
| SOCKS5 | Depende de la fuente | Alta | Protocolo universal, soportado por Playwright |
Para la mayoría de las tareas de scraping, la elección óptima son los proxies residenciales con rotación. Tienen IP reales de usuarios domésticos, por lo que los sitios no los identifican como de centro de datos y no los bloquean automáticamente. Para sitios con protección agresiva (Cloudflare Bot Management, Akamai), es mejor usar proxies móviles, ya que sus IP pertenecen a operadores de telefonía móvil, lo que genera la máxima confianza.
Playwright soporta los protocolos http, https y socks5. Importante: SOCKS5 no soporta la autenticación a través de username:password directamente en algunas versiones — más detalles en la sección de errores.
Configuración básica de proxy en Playwright (JavaScript y Python)
Playwright permite especificar un proxy al iniciar el navegador a través del parámetro proxy. Este es el método más sencillo: todas las solicitudes del navegador pasarán a través del proxy especificado.
JavaScript / Node.js
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({
proxy: {
server: 'http://proxy.example.com:8080'
}
});
const page = await browser.newPage();
await page.goto('https://httpbin.org/ip');
const content = await page.textContent('body');
console.log(content); // mostrará la IP del servidor proxy
await browser.close();
})();
Python
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(
proxy={
"server": "http://proxy.example.com:8080"
}
)
page = browser.new_page()
page.goto("https://httpbin.org/ip")
print(page.text_content("body")) # mostrará la IP del proxy
browser.close()
Para SOCKS5, simplemente cambia el esquema en la dirección del servidor:
# Python — proxy SOCKS5
browser = p.chromium.launch(
proxy={
"server": "socks5://proxy.example.com:1080"
}
)
Para verificar rápidamente que el proxy está funcionando, abre https://httpbin.org/ip o https://api.ipify.org — en la respuesta debe aparecer la IP del proxy, no tu IP real.
Proxy con autenticación por nombre de usuario y contraseña
La mayoría de los proveedores de proxies comerciales utilizan autenticación por nombre de usuario y contraseña — esta es una práctica estándar. Playwright la admite a través de los campos username y password en el objeto proxy.
JavaScript
const browser = await chromium.launch({
proxy: {
server: 'http://gate.proxyprovider.com:7777',
username: 'your_login',
password: 'your_password'
}
});
Python
browser = p.chromium.launch(
proxy={
"server": "http://gate.proxyprovider.com:7777",
"username": "your_login",
"password": "your_password"
}
)
También puedes pasar el nombre de usuario y la contraseña directamente en la URL del servidor proxy — esto es conveniente si estás generando la cadena dinámicamente:
# Autenticación en la URL (Python)
proxy_url = f"http://{login}:{password}@gate.proxyprovider.com:7777"
browser = p.chromium.launch(
proxy={"server": proxy_url}
)
⚠️ Atención
¡No almacenes el nombre de usuario y la contraseña del proxy directamente en el código! Utiliza variables de entorno (os.environ en Python o process.env en Node.js) o un archivo .env con la biblioteca dotenv.
Almacenamiento seguro a través de .env (Python)
import os
from dotenv import load_dotenv
from playwright.sync_api import sync_playwright
load_dotenv()
PROXY_SERVER = os.getenv("PROXY_SERVER")
PROXY_LOGIN = os.getenv("PROXY_LOGIN")
PROXY_PASSWORD = os.getenv("PROXY_PASSWORD")
with sync_playwright() as p:
browser = p.chromium.launch(
proxy={
"server": PROXY_SERVER,
"username": PROXY_LOGIN,
"password": PROXY_PASSWORD
}
)
# ...
Rotación de proxies: cambio de IP para cada solicitud
Un solo proxy no te salvará de un bloqueo con un gran volumen de solicitudes. Para un scraping serio, se necesita rotación de IP — cambio automático del servidor proxy a intervalos determinados o para cada nueva solicitud.
Hay dos enfoques para la rotación en Playwright:
Enfoque 1: Endpoint de proxy rotativo
La mayoría de los proveedores de proxies residenciales ofrecen una única dirección de gateway, que cambia automáticamente la IP en cada conexión. No necesitas escribir la lógica de rotación — está integrada del lado del proveedor.
# Un endpoint — nueva IP en cada conexión del navegador
browser = p.chromium.launch(
proxy={
"server": "http://rotating.proxyprovider.com:8888",
"username": "your_login",
"password": "your_password"
}
)
Enfoque 2: Rotación manual a través de una lista de proxies
Si tienes una lista de proxies estáticos, puedes implementar la rotación manualmente — creando un nuevo navegador o contexto para cada iteración:
import random
from playwright.sync_api import sync_playwright
PROXY_LIST = [
{"server": "http://proxy1.example.com:8080", "username": "user", "password": "pass"},
{"server": "http://proxy2.example.com:8080", "username": "user", "password": "pass"},
{"server": "http://proxy3.example.com:8080", "username": "user", "password": "pass"},
]
URLS_TO_SCRAPE = [
"https://example.com/page1",
"https://example.com/page2",
"https://example.com/page3",
]
with sync_playwright() as p:
for url in URLS_TO_SCRAPE:
proxy = random.choice(PROXY_LIST) # proxy aleatorio
browser = p.chromium.launch(proxy=proxy)
page = browser.new_page()
page.goto(url)
# ... scraping de datos ...
browser.close() # cerramos el navegador, cambiamos IP
Enfoque 3: Rotación a través de BrowserContext (sin reiniciar el navegador)
with sync_playwright() as p:
browser = p.chromium.launch() # navegador sin proxy
for i, url in enumerate(URLS_TO_SCRAPE):
proxy = PROXY_LIST[i % len(PROXY_LIST)] # en círculo
# Nuevo contexto con nuevo proxy — más rápido que reiniciar el navegador
context = browser.new_context(proxy=proxy)
page = context.new_page()
page.goto(url)
# ... scraping ...
context.close() # cerramos el contexto, no el navegador
browser.close()
El tercer enfoque es el más eficiente para scraping masivo. Reiniciar el navegador toma de 2 a 4 segundos, mientras que crear un nuevo contexto toma menos de 100 milisegundos.
Proxy a nivel de contexto y página
Playwright admite una arquitectura flexible: un navegador puede tener varios contextos aislados, cada uno con su propio proxy. Esto permite trabajar simultáneamente con varias IP dentro de un mismo proceso.
Varios contextos con diferentes proxies (scraping paralelo)
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
// Contexto 1 — proxy de Alemania
const context_de = await browser.newContext({
proxy: {
server: 'http://de-proxy.example.com:8080',
username: 'user',
password: 'pass'
}
});
// Contexto 2 — proxy de EE. UU.
const context_us = await browser.newContext({
proxy: {
server: 'http://us-proxy.example.com:8080',
username: 'user',
password: 'pass'
}
});
const page_de = await context_de.newPage();
const page_us = await context_us.newPage();
// Ejecución paralela
await Promise.all([
page_de.goto('https://example.com'),
page_us.goto('https://example.com')
]);
// Ambas páginas ven diferentes IP
console.log('DE IP:', await page_de.textContent('body'));
console.log('US IP:', await page_us.textContent('body'));
await browser.close();
})();
Este enfoque es ideal para pruebas de geolocalización: verificas simultáneamente cómo se muestra el sitio a usuarios de diferentes países, sin tener que ejecutar múltiples instancias del navegador.
💡 Consejo de rendimiento
Para máxima paralelidad, utiliza asyncio en Python o Promise.all en Node.js. Un navegador puede mantener de 10 a 20 contextos paralelos sin una carga significativa en la memoria.
Elusión de protección contra bots: Cloudflare, Akamai, DataDome
Un proxy es solo parte de la solución. Los sistemas modernos de protección contra bots analizan decenas de señales simultáneamente: huella digital del navegador, comportamiento del mouse, velocidad de llenado de formularios, encabezados HTTP y mucho más. Incluso con un buen proxy, puedes ser bloqueado si no tienes en cuenta estos factores.
1. Ocultación del modo sin cabeza
Playwright en modo sin cabeza tiene características distintivas que son fácilmente identificables: valores específicos de navigator.webdriver, ausencia de plugins, tamaños de pantalla no estándar. Utiliza la biblioteca playwright-stealth para ocultar:
# Python: instalación
# pip install playwright-stealth
from playwright.sync_api import sync_playwright
from playwright_stealth import stealth_sync
with sync_playwright() as p:
browser = p.chromium.launch(
proxy={
"server": "http://residential.proxyprovider.com:8888",
"username": "user",
"password": "pass"
}
)
page = browser.new_page()
stealth_sync(page) # aplicamos la ocultación
page.goto("https://bot.sannysoft.com") # prueba de detección de bots
browser.close()
2. User-Agent y viewport realistas
context = browser.new_context(
proxy={
"server": "http://proxy.example.com:8080",
"username": "user",
"password": "pass"
},
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
viewport={"width": 1920, "height": 1080},
locale="es-ES",
timezone_id="Europe/Madrid" # debe coincidir con la geolocalización del proxy!
)
3. Simulación del comportamiento humano
import time
import random
# Retrasos aleatorios entre acciones
def human_delay(min_ms=500, max_ms=2000):
time.sleep(random.randint(min_ms, max_ms) / 1000)
page.goto("https://example.com")
human_delay()
# Desplazamiento suave en lugar de instantáneo
page.evaluate("window.scrollBy({top: 500, behavior: 'smooth'})")
human_delay(300, 800)
# Movimiento del mouse antes de hacer clic
page.mouse.move(100, 200)
human_delay(100, 300)
page.mouse.move(300, 400)
human_delay(100, 200)
page.click("button#submit")
4. Coincidencia de la zona horaria con la geolocalización del proxy
Esto a menudo se ignora, pero los sistemas de protección contra bots verifican la correspondencia: si tu proxy es de Moscú y el navegador muestra la zona horaria UTC-8 (Los Ángeles) — es una bandera roja. Siempre establece timezone_id de acuerdo con la geolocalización del proxy utilizado.
Errores comunes y cómo solucionarlos
Al trabajar con proxies en Playwright, los desarrolladores se enfrentan regularmente a los mismos problemas. Analicemos cada uno con una solución concreta.
Error 1: ERR_PROXY_CONNECTION_FAILED
Razón: Dirección o puerto del proxy incorrectos, proxy no disponible, credenciales incorrectas.
Solución: Verifica la disponibilidad del proxy a través de curl antes de iniciar Playwright:
# Verificación del proxy a través de curl
curl -x http://user:[email protected]:8080 https://api.ipify.org
Error 2: SOCKS5 no acepta autenticación
Razón: Playwright (Chromium) tiene soporte limitado para SOCKS5 con autenticación a través de username/password.
Solución: Utiliza proxies HTTP con autenticación o configura un túnel SOCKS5 local a través de ssh -D sin contraseña.
Error 3: El proxy funciona, pero el sitio aún bloquea
Razón: Se utilizan proxies de centro de datos que están en listas negras; el modo sin cabeza no está oculto; frecuencia de solicitudes demasiado alta.
Solución: Cambia a proxies residenciales o móviles, agrega playwright-stealth, aumenta los retrasos entre solicitudes.
Error 4: Fuga de IP real (fuga de DNS)
Razón: Las solicitudes DNS pueden eludir el proxy.
Solución: Playwright redirige DNS a través del proxy por defecto al usar proxies HTTP. Pero para verificar, utiliza https://dnsleaktest.com en el navegador sin cabeza.
Error 5: Funcionamiento lento con el proxy
Razón: Los proxies residenciales son más lentos que los de centros de datos; gran distancia hasta el servidor proxy.
Solución: Elige proxies en ubicaciones geográficamente cercanas. Para tareas sin estrictos requisitos de anonimato, utiliza proxies de centros de datos — son significativamente más rápidos.
| Error | Solución rápida |
|---|---|
| ERR_PROXY_CONNECTION_FAILED | Verificar curl, nombre de usuario/contraseña, disponibilidad del puerto |
| 407 Proxy Auth Required | Agregar nombre de usuario y contraseña en la configuración del proxy |
| El sitio muestra CAPTCHA | Cambiar el tipo de proxy a residenciales, agregar stealth |
| La IP no cambia durante la rotación | Cerrar el contexto/navegador entre solicitudes |
| Tiempo de espera de conexión | Aumentar timeout en goto(), elegir un proxy más cercano |
Conclusión y recomendaciones
Configurar un proxy en Playwright no es una tarea única, sino parte de la arquitectura de tu herramienta de automatización. Un tipo de proxy bien elegido, una rotación de IP adecuada y la ocultación del modo sin cabeza en conjunto proporcionan un funcionamiento estable incluso en sitios con protección agresiva contra bots.
Resumamos la elección del tipo de proxy para tareas específicas:
- Scraping de datos abiertos sin protección estricta — son adecuados los proxies rápidos de centros de datos.
- Marketplaces (Wildberries, Ozon), agregadores de noticias — se necesitan proxies residenciales con rotación.
- Redes sociales (Instagram, Facebook, TikTok) y sitios con Cloudflare — solo proxies móviles o residenciales.
- Pruebas de geolocalización — cualquier tipo de proxy en el país necesario, lo principal es la coincidencia de la zona horaria.
- Scraping masivo con alta frecuencia — proxies residenciales rotativos con endpoint de gateway.
Si estás construyendo un sistema de scraping o pruebas automatizadas en Playwright y necesitas un funcionamiento estable sin bloqueos, te recomendamos considerar proxies residenciales — proporcionan un alto nivel de confianza por parte de los sitios y soportan la rotación de IP a través de un único endpoint, lo que simplifica la integración con Playwright a solo unas pocas líneas de código.