Si has intentado automatizar Chrome con Playwright contra un sitio protegido por Cloudflare Turnstile o DataDome, ya sabes el resultado: un desafío CAPTCHA infinito o un bloqueo 403 en la tercera petición. El análisis profundo de Patchright que desarrollamos aquí explica por qué los navegadores headless detectables fallan, qué parchea exactamente Patchright frente a alternativas como playwright-stealth o Camoufox, y por qué cerrar las fugas del protocolo CDP no basta si tu IP sigue siendo un rango datacenter conocido. La solución completa requiere alinear tres capas: fingerprint del navegador, reputación de IP y coherencia TLS/JA3 con el nodo de salida.
Qué es Patchright y por qué existe el análisis profundo de Patchright
Patchright es un fork de Playwright que aplica parches a nivel de binario y de lanzamiento para eliminar las señales de automatización más comunes que los sistemas anti-bot detectan en Chromium. No es un plugin ni un script de inyección: modifica cómo se construye el proceso del navegador y qué flags se pasan al binario de Chrome. Esto lo diferencia fundamentalmente de playwright-stealth, que solo inyecta scripts JavaScript en tiempo de ejecución para sobrescribir propiedades del DOM.
El problema que Patchright resuelve es real y medible. Cuando lanzas Chrome con Playwright estándar, el navegador expone múltiples señales de automatización que un detector puede consultar en milisegundos: navigator.webdriver devuelve true, el protocolo CDP (Chrome DevTools Protocol) deja rastros detectables, y los flags de línea de comandos incluyen --enable-automation que altera el comportamiento del navegador. Cloudflare, DataDome, Akamai Bot Manager y PerimeterX consultan estas señales en la primera petición, antes de que tu script siquiera haya cargado la página.
Las señales de detección que Patchright elimina
Patchright aborda cuatro categorías principales de detección:
- navigator.webdriver: En Playwright estándar,
navigator.webdriverestrue. Patchright fuerza este valor afalsesin depender de un script de inyección que un detector podría interceptar. Lo hace parcheando el código fuente de Chromium antes de la compilación, eliminando la propiedad en el bindings de V8. Puedes leer más sobre esta API en la documentación de MDN sobre Navigator.webdriver. - Fugas del runtime CDP: Playwright usa el Chrome DevTools Protocol para controlar el navegador. La llamada
Runtime.enabledeja evidencia en el contexto de ejecución. Los detectores avanzados consultanwindow.cdc_adoQpoasnfa76pfcZLmcfl_Arrayy otros artefactos del protocolo. Patchright minimiza estas fugas limpiando el runtime y eliminando variables expuestas que delatan la presencia de DevTools activo. - Flags de línea de comandos: Patchright inyecta
--disable-blink-features=AutomationControlledautomáticamente. Este flag elimina la característica de Blink que establecenavigator.webdriver=truey que añade el banner de "Chrome is being controlled by automated test software". En Playwright estándar tendrías que pasar este flag manualmente y aún así otras señales persisten. - Stack TLS/JA3 real: Patchright recomienda usar
channel='chrome'para lanzar el binario real de Chrome instalado en el sistema, no el Chromium compilado que Playwright descarga por defecto. Esto produce un ClientHello TLS con el orden de cipher suites exacto que un usuario real de Chrome enviaría, generando un hash JA3 coherente con el navegador declarado en el User-Agent.
El uso de channel='chrome' es crítico. Chromium compilado por Playwright tiene un JA3 distinto al de Chrome estable porque usa una versión de BoringSSL diferente y el orden de extensiones TLS varía. Los sistemas anti-bot que comparan el JA3 del ClientHello contra una base de datos de hashes conocidos detectan esta discrepancia inmediatamente. Puedes consultar el detalle del protocolo TLS 1.3 en el RFC 8446 del IETF.
Lo que Patchright parchea y lo que no
Aquí es donde el análisis profundo de Patchright se vuelve matizado. Patchright cierra las fugas más obvias del navegador, pero no cubre todo. Entender el límite es lo que separa una implementación que pasa detección de una que falla en el segundo intento.
Lo que Patchright cubre bien
navigator.webdriver = falsesin inyección JS detectable.- Eliminación del banner "controlled by automated software".
- Limpieza de artefactos CDP en el runtime (
Runtime.enabletraces). - Flags de automatización en línea de comandos (
--enable-automationremovido). - JA3 coherente cuando se usa
channel='chrome'.
Lo que Patchright NO cubre
- Canvas fingerprinting: Patchright no modifica el rendering del canvas. El hash de un canvas con texto y formas sigue siendo el mismo en cada ejecución. Un detector que compara tu canvas hash contra una base de datos de hashes datacenter lo detectará. Camoufox, por el contrario, añade ruido determinista al rendering del canvas.
- WebGL fingerprinting: Los parámetros de WebGL (
UNMASKED_VENDOR_WEBGL,UNMASKED_RENDERER_WEBGL) revelan la GPU real del servidor. Si ejecutas en un VPS con una GPU virtualizada, el renderer seráSwiftShadero similar, lo cual es una señal inmediata de headless. - Fuentes instaladas: La lista de fuentes disponibles en el sistema delata el entorno. Un servidor Linux headless no tiene Helvetica ni Calibri. Patchright no añade fuentes.
- Señales de comportamiento: La velocidad de escritura, el movimiento del ratón, los intervalos entre eventos y la distribución de pausas humanas no son simulados por Patchright. DataDome mide la entropía de estos eventos.
- Screen y window dimensions: En headless, las dimensiones de pantalla pueden ser inusuales o inconsistentes con el User-Agent declarado.
Comparación: Patchright vs Camoufox vs playwright-stealth
| Característica | Patchright | Camoufox | playwright-stealth |
|---|---|---|---|
| navigator.webdriver | Parche a nivel binario | Parche a nivel binario (Firefox) | Inyección JS (detectable) |
| Fugas CDP Runtime.enable | Cubiertas | N/A (usa Firefox, no CDP) | No cubiertas |
| Canvas fingerprinting | No cubierto | Ruido determinista aplicado | No cubierto |
| WebGL spoofing | No cubierto | Vendor/Renderer spoofed | No cubierto |
| JA3/TLS coherente | Sí (con channel='chrome') | Sí (Firefox real) | Depende del navegador base |
| Motor | Chromium (Chrome real) | Firefox (Gecko modificado) | Cualquier (Playwright) |
| Mantenimiento activo | Sí | Sí | Limitado |
La conclusión práctica: Patchright es la opción más sólida para sitios donde la detección principal se basa en CDP y navigator.webdriver. Camoufox es superior cuando el canvas y WebGL fingerprinting son el vector de detección. playwright-stealth es insuficiente para cualquier sistema anti-bot moderno porque la inyección JS es detectable: los sistemas anti-bot pueden comparar el comportamiento del script antes y después de la inyección para identificar la sobrescritura.
Por qué la reputación de IP importa después de cerrar las fugas CDP
Aquí está el punto donde muchos ingenieros fallan. Cerraste navigator.webdriver, eliminaste las fugas CDP, usas Chrome real con un JA3 coherente. Tu script pasa los primeros checks de Cloudflare. Pero en la tercera petición, recibes un 403. ¿Por qué?
La respuesta es que los sistemas anti-bot modernos no se basan en una sola señal. Puntúan en un modelo de riesgo que combina cientos de features. Después de que las señales del navegador están limpias, la siguiente categoría con más peso es la reputación de la IP de origen. Un servidor en AWS, DigitalOcean, u OVH tiene un ASN que está en listas de IPs datacenter conocidas. Cloudflare Turnstile y DataDome consultan bases de datos de ASN en tiempo real y asignan un score de riesgo alto a cualquier IP que pertenezca a un rango datacenter, sin importar cuán limpio sea tu navegador.
En la práctica, hemos visto que con un proxy datacenter y Patchright correctamente configurado, la tasa de éxito contra Cloudflare Turnstile cae del 95% inicial al 30% después de 50 peticiones desde la misma IP. Con un proxy residencial rotativo, la tasa de éxito se mantiene por encima del 90% en el mismo volumen. La diferencia es la reputación del ASN.
Los proxies residenciales funcionan porque la IP de salida pertenece a un ISP residencial real (Comcast, AT&T, Movistar, Vodafone). El ASN del proxy residencial no está en las listas de IPs datacenter. El sistema anti-bot ve una IP que pertenece a un consumidor doméstico, no a un servidor, y reduce el score de riesgo. Puedes consultar las características de Cloudflare Turnstile para entender cómo combina señales de navegador con reputación de IP.
La regla fundamental: un navegador indetectable con una IP detectable sigue siendo detectable. El fingerprint del navegador y la reputación de la IP son capas independientes que ambos deben ser coherentes.
Coherencia TLS/HTTP2 y alineación del fingerprint con la IP de salida
El último nivel de detección es el más sutil y el que menos desarrolladores consideran. Cuando tu navegador envía el ClientHello TLS, el servidor no solo ve el JA3 hash: lo compara con el contexto completo de la conexión. Si tu IP de salida está en Estados Unidos pero tu TLS ClientHello coincide con un perfil de Chrome en español de Latinoamérica, hay una inconsistencia menor. Si tu IP es residencial en Alemania pero tu navegador envía un JA3 que coincide con una versión de Chrome que no se usa en Europa, la inconsistencia es mayor.
El JA4 fingerprint (la evolución del JA3 que incluye el ALPN y los extensiones SNI) añade más granularidad. Un detector puede comparar:
- El país del ASN de la IP de salida.
- El idioma del Accept-Language header.
- El timezone del navegador (
Intl.DateTimeFormat().resolvedOptions().timeZone). - El JA4 hash del ClientHello.
Si todos estos no cuentan una historia coherente, el score de riesgo sube. La alineación correcta significa:
- Usar un proxy residencial en el país objetivo (ej. US).
- Configurar el timezone del navegador para coincidir con ese país (
America/New_York). - Establecer el
Accept-Languageapropiado (en-US,en;q=0.9). - Usar
channel='chrome'para que el JA3/JA4 sea el de Chrome real. - Mantener la misma sesión de proxy para que la IP no cambie entre peticiones.
Esta coherencia es lo que distingue una implementación profesional de un script que funciona una vez y falla en producción.
Implementación práctica: Patchright con proxies residenciales de ProxyHat
A continuación, un ejemplo completo de una implementación legítima: un contexto persistente de Patchright enrutado a través de un proxy residencial de ProxyHat con sesión fija en Estados Unidos. Este ejemplo es apropiado para investigación de seguridad autorizada o automatización de datos públicos en cumplimiento con los términos de servicio del sitio objetivo.
Requisitos previos
pip install patchright proxyhat-sdk
patchright install chrome
Script de implementación
from patchright.sync_api import sync_playwright
import json
import time
# Configuración del proxy residencial ProxyHat
# Sesión fija para mantener la misma IP en todas las peticiones
PROXY_USER = "user-country-US-session-abc123"
PROXY_PASS = "tu_password_aqui"
PROXY_HOST = "gate.proxyhat.com"
PROXY_PORT = 8080
proxy_url = f"http://{PROXY_USER}:{PROXY_PASS}@{PROXY_HOST}:{PROXY_PORT}"
with sync_playwright() as p:
# Usar channel='chrome' para el JA3/JA4 real de Chrome
# Contexto persistente para mantener cookies y estado
context = p.chromium.launch_persistent_context(
user_data_dir="./browser_profile",
channel="chrome",
headless=False, # headless=False reduce detección adicional
proxy={
"server": f"http://{PROXY_HOST}:{PROXY_PORT}",
"username": PROXY_USER,
"password": PROXY_PASS,
},
timezone="America/New_York",
locale="en-US",
viewport={"width": 1920, "height": 1080},
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/131.0.0.0 Safari/537.36",
args=[
"--disable-blink-features=AutomationControlled",
"--disable-features=IsolateOrigins,site-per-process",
"--disable-site-isolation-trials",
],
)
page = context.new_page()
# Navegar a la página objetivo
page.goto("https://example.com", wait_until="networkidle", timeout=60000)
# Esperar a que la página cargue completamente
time.sleep(3)
# Verificar contenido
title = page.title()
print(f"Título de la página: {title}")
# Realizar acciones legítimas aquí
# ...
context.close()
Variante con Node.js
const { chromium } = require('patchright');
const proxyUser = 'user-country-US-session-abc123';
const proxyPass = 'tu_password_aqui';
const proxyHost = 'gate.proxyhat.com';
const proxyPort = 8080;
(async () => {
const browser = await chromium.launchPersistentContext(
'./browser_profile',
{
channel: 'chrome',
headless: false,
proxy: {
server: `http://${proxyHost}:${proxyPort}`,
username: proxyUser,
password: proxyPass,
},
timezone: 'America/New_York',
locale: 'en-US',
viewport: { width: 1920, height: 1080 },
args: [
'--disable-blink-features=AutomationControlled',
],
}
);
const page = await browser.newPage();
await page.goto('https://example.com', {
waitUntil: 'networkidle',
timeout: 60000,
});
console.log('Título:', await page.title());
await browser.close();
})();
Verificación con curl
curl -x http://user-country-US-session-abc123:tu_password@gate.proxyhat.com:8080 \
https://api.ipify.org?format=json
Este comando confirma que la IP de salida es residencial y está en Estados Unidos. Antes de ejecutar el script completo, verifica siempre que el proxy funciona y que la IP de salida es la esperada.
Configuración de SOCKS5
Si necesitas SOCKS5 en lugar de HTTP (útil para ciertas aplicaciones que requieren tunneling a nivel TCP), usa el puerto 1080:
socks5://user-country-US-session-abc123:tu_password@gate.proxyhat.com:1080
En Patchright, cambia la configuración del proxy:
proxy={
"server": f"socks5://{PROXY_HOST}:1080",
"username": PROXY_USER,
"password": PROXY_PASS,
}
Errores comunes y casos límite
1. No usar channel='chrome'
Si omites channel='chrome', Playwright descarga un Chromium compilado con un JA3 distinto al de Chrome estable. El navegador se ve legítimo en JavaScript pero el TLS ClientHello no coincide con ningún perfil de Chrome real en las bases de datos de JA3. Solución: siempre usa channel='chrome' e instala Chrome estable en tu servidor.
2. Cambiar de IP en cada petición con sesiones rotativas
Algunos desarrolladores configuran rotación de IP por petición. Esto es contraproducente para sitios que usan sesiones. Cloudflare Turnstile, por ejemplo, emite un token que se valida contra la IP que lo generó. Si la IP cambia entre la petición del desafío y la validación, el token se invalida. Solución: usa sesiones fijas (session-abc123) y rota solo cuando la sesión se bloquee o expire.
3. Timezone inconsistente con la IP
Si tu proxy es de Estados Unidos pero tu navegador tiene timezone Europe/Madrid, un detector que compare Intl.DateTimeFormat().resolvedOptions().timeZone con el país del ASN de la IP lo detectará. Solución: configura el timezone en el contexto del navegador para coincidir con el país del proxy.
4. No manejar el viewport en headless
En headless, el viewport por defecto puede ser 800x600, lo cual es inusual para un usuario real. Configura un viewport realista como 1920x1080 o 1366x768 (el más común según datos de uso de resoluciones de pantalla).
5. Ignorar el Accept-Language header
El header Accept-Language debe coincidir con el locale del navegador y el país de la IP. Si tu proxy es de US pero envías Accept-Language: es-ES, hay una inconsistencia. Solución: configura locale='en-US' en el contexto y deja que Patchright maneje el header automáticamente.
Configuración específica de ProxyHat
ProxyHat ofrece proxies residenciales, móviles y datacenter. Para escenarios de detección anti-bot como los descritos aquí, los proxies residenciales son la opción correcta. Los proxies datacenter son útiles para tareas donde la reputación de IP no es un factor (APIs públicas, scraping de sitios sin protección anti-bot, testing de latencia).
La configuración de geo-targeting de ProxyHat permite especificar país y ciudad en el nombre de usuario:
# Proxy residencial en Berlín, Alemania
http://user-country-DE-city-berlin-session-xyz789:pass@gate.proxyhat.com:8080
# Proxy residencial en Tokio, Japón
http://user-country-JP-city-tokyo-session-def456:pass@gate.proxyhat.com:8080
Para ver todas las ubicaciones disponibles, consulta nuestra página de ubicaciones. Los detalles completos de la API y configuración están en la documentación oficial de ProxyHat.
Para comparar planes y precios según el tipo de proxy que necesitas, visita nuestra página de precios. Si estás construyendo un pipeline de scraping más amplio, nuestro caso de uso de web scraping cubre estrategias de rotación y gestión de sesiones a mayor escala.
Dónde es apropiado usar esta técnica
El análisis profundo de Patchright tiene un propósito legítimo y claramente delimitado:
- Investigación de seguridad autorizada: Pentesting con autorización explícita del propietario del sistema, donde necesitas simular tráfico realista para evaluar la efectividad de las defensas anti-bot.
- Auditoría de tu propia infraestructura: Verificar que tus sistemas anti-bot funcionan correctamente contra navegadores indetectables.
- Automatización de datos públicos: Recolección de datos que son públicamente accesibles sin autenticación, en cumplimiento con los términos de servicio del sitio y respetando
robots.txt. - Investigación de SERP: Seguimiento de posiciones en buscadores para SEO, un caso de uso cubierto en nuestro artículo de SERP tracking.
- Monitoreo de precios público: Comparación de precios de productos visibles públicamente, respetando rate limits razonables.
Lo que nunca es apropiado:
- Acceso a contenido detrás de login sin autorización.
- Compra automatizada de productos limitados (sneaker botting, ticketing) que viola términos de servicio.
- Fraude publicitario o generación de clics artificiales.
- Evadir bloqueos de IP por comportamiento abusivo previo.
- Cualquier actividad que viole GDPR, CCPA, o regulaciones locales de protección de datos.
La línea es clara: si necesitas credenciales que no te pertenecen o si estás accediendo a contenido que el sitio explícitamente restringe a usuarios humanos, estás fuera del ámbito legítimo. Patchright y los proxies residenciales son herramientas para reducir fricción en acceso autorizado, no para evadir controles de seguridad en sistemas donde no tienes autorización.
Conclusiones clave
- Patchright cierra las fugas de navegador más comunes (navigator.webdriver, CDP Runtime.enable, flags de automatización) pero no cubre canvas, WebGL, fuentes ni comportamiento. Para esos vectores, considera Camoufox o complementa con técnicas adicionales.
- La reputación de IP es independiente del fingerprint del navegador. Un navegador perfecto con una IP datacenter sigue siendo detectable. Los proxies residenciales son necesarios contra Cloudflare Turnstile y DataDome.
- La coherencia TLS/JA3/JA4 con la IP de salida es el nivel más sutil de detección. Usa
channel='chrome'y alinea timezone, locale y país del proxy. - Las sesiones fijas son superiores a la rotación por petición para sitios que usan tokens anti-bot vinculados a la IP.
- El uso legítimo es no negociable: investigación de seguridad autorizada, datos públicos y auditoría propia. Nunca fraude ni acceso no autorizado.
- ProxyHat en gate.proxyhat.com:8080 (HTTP) o :1080 (SOCKS5) con geo-targeting por país y ciudad, y sesiones fijas vía el flag
session-en el nombre de usuario.
Para empezar a integrar Patchright con proxies residenciales de ProxyHat, revisa nuestra página de precios y la documentación técnica. Si necesitas coberturas específicas por país, consulta nuestras ubicaciones disponibles.






