
Colección de parches para puppeteer y playwright para evitar la detección de automatización y las fugas de información. Ayuda a evitar las páginas CAPTCHA de Cloudflare y DataDome. Fácil de parchear/desparchear, se puede habilitar/deshabilitar bajo demanda.
Este repositorio contiene parches para mejorar las bibliotecas populares de automatización web. Específicamente, se dirige a los paquetes puppeteer y playwright.
Algunos aspectos de las bibliotecas de automatización o del comportamiento del navegador no se pueden ajustar mediante configuraciones o parámetros de línea de comandos. Por lo tanto, solucionamos estos problemas parcheando el código fuente de la biblioteca. Si bien este enfoque es frágil y puede romperse a medida que el código fuente de las bibliotecas cambia con el tiempo, el objetivo es mantener este repositorio con ayuda de la comunidad para mantener los parches actualizados.
De fábrica, Puppeteer y Playwright vienen con algunas fugas significativas que son fáciles de detectar. No importa lo buenos que sean tus proxies, huellas digitales y scripts de comportamiento: si no lo tienes parcheado, eres una gran bandera roja para cualquier sitio web importante.
🕵️ Puedes probar fácilmente tu configuración de automatización frente a las principales detecciones modernas con rebrowser-bot-detector (fuentes y detalles)
| Antes de los parches 👎 | Después de los parches 👍 |
|---|---|
![]() | ![]() |
Si no quieres lidiar con los parches y todos los posibles errores, existe una solución de reemplazo directo para ti. Estos paquetes simplemente han aplicado rebrowser-patches sobre el código original, nada más.
Puppeteer: rebrowser-puppeteer (código fuente) y rebrowser-puppeteer-core (código fuente)
Playwright (Node.js): rebrowser-playwright (código fuente) y rebrowser-playwright-core (código fuente)
Playwright (Python): rebrowser-playwright (código fuente)
La forma más fácil de empezar a usarlo es modificar tu package.json para usar los nuevos paquetes pero mantener el nombre antiguo como alias. De esta manera, no necesitas cambiar ningún código fuente de tu automatización. Así es como se hace:
package.json y reemplaza "puppeteer": "^23.3.1" y "puppeteer-core": "^23.3.1" por "puppeteer": "npm:rebrowser-puppeteer@^23.3.1" y "puppeteer-core": "npm:rebrowser-puppeteer-core@^23.3.1". Nota: 23.3.1 es solo un ejemplo; consulta la última versión en npm.npm install (o yarn install)Otra forma es usar directamente los nuevos paquetes en lugar de los originales. Estos son los pasos que debes seguir:
package.json y reemplaza los paquetes puppeteer y puppeteer-core por rebrowser-puppeteer y rebrowser-puppeteer-core. No cambies las versiones de los paquetes, solo reemplaza los nombres.npm install (o yarn install)puppeteer y puppeteer-core por rebrowser-puppeteer y rebrowser-puppeteer-core🚀 ¡Eso es todo! Solo visita la página de rebrowser-bot-detector y prueba tu navegador parcheado.
Nuestro objetivo es mantener y dar soporte a estos paquetes de reemplazo directo con las últimas versiones, pero nos centramos principalmente en versiones recientes, así que si todavía estás usando puppeteer 13.3.7 de principios de los 90, puede ser un buen momento para actualizar. Hay una alta probabilidad de que realmente no rompa nada, ya que la API es bastante estable con el tiempo.
Runtime.EnableLas bibliotecas de automatización populares dependen del comando CDP Runtime.Enable, que permite recibir eventos del dominio Runtime.. Esto es crucial para gestionar los contextos de ejecución utilizados para evaluar JavaScript en las páginas, una característica clave para cualquier proceso de automatización.
Sin embargo, existe una técnica que detecta el uso de este comando, revelando que el navegador está controlado por software de automatización como Puppeteer o Playwright. Esta técnica es utilizada por todo el software anti-bot importante, como Cloudflare, DataDome y otros.
Hemos preparado un artículo completo sobre nuestra investigación de esta fuga, que puedes leer en nuestro blog.
Para más detalles sobre esta técnica, lee la publicación del blog de DataDome: Cómo el nuevo Headless Chrome y la señal CDP están impactando la detección de bots.
En resumen, son unas pocas líneas de JavaScript en la página que se llaman automáticamente si se usó Runtime.Enable.
Nuestra corrección desactiva el comando automático Runtime.Enable en cada frame. En su lugar, creamos manualmente contextos con IDs desconocidos cuando se crea un frame. Luego, cuando se necesita ejecutar código, hay múltiples maneras de obtener el ID de contexto.
🟢 Pros: El enfoque definitivo que mantiene el acceso al mundo principal y funciona con web workers e iframes. No necesitas cambiar nada de tu código existente.
🔴 Contras: Hasta ahora no se ha descubierto ninguno.
Page.createIsolatedWorld y guardar su ID.🟢 Pros: Todo tu código se ejecutará en un mundo aislado separado, evitando que los scripts de la página detecten tus cambios mediante MutationObserver y otras técnicas.
🔴 Contras: No podrás acceder a las variables y al código del contexto principal. Si bien esto es necesario para algunos casos de uso, el contexto aislado generalmente funciona bien para la mayoría de los escenarios. Además, los web workers no permiten crear nuevos mundos, por lo que no puedes ejecutar tu código dentro de un worker. Es un caso de uso de nicho, pero puede ser importante en algunas situaciones. Existe una solución alternativa para este problema; lee Cómo acceder a objetos del contexto principal desde un contexto aislado en Puppeteer y Playwright.
Runtime.Enable y luego inmediatamente a Runtime.Disable.Esto activa los eventos Runtime.executionContextCreated, lo que nos permite capturar el ID de contexto adecuado.
🟢 Pros: Tendrás acceso completo al contexto principal.
🔴 Contras: Existe una pequeña posibilidad de que durante este breve intervalo de tiempo, la página ejecute código que provoque la fuga. El riesgo es bajo, ya que el código de detección generalmente se ejecuta durante acciones específicas como páginas CAPTCHA o formularios de inicio de sesión/registro, normalmente justo después de que la página carga. Tu lógica de negocio generalmente se ejecuta un poco más tarde.
🎉 Nuestras pruebas muestran que todos estos enfoques son actualmente indetectables por Cloudflare o DataDome.
Nota: puedes cambiar la configuración de este parche sobre la marcha usando una variable de entorno. Esto te permite cambiar fácilmente entre versiones parcheadas y sin parchear según tu lógica de negocio.
REBROWSER_PATCHES_RUNTIME_FIX_MODE=addBinding — técnica addBinding (predeterminada)REBROWSER_PATCHES_RUNTIME_FIX_MODE=alwaysIsolated — ejecutar siempre todos los scripts en contexto aisladoREBROWSER_PATCHES_RUNTIME_FIX_MODE=enableDisable — usar la técnica Enable/DisableREBROWSER_PATCHES_RUNTIME_FIX_MODE=0 — desactivar completamente la corrección para esta fugaREBROWSER_PATCHES_DEBUG=1 — habilitar algunos mensajes de depuraciónRecuerda que puedes establecer estas variables de diferentes maneras, por ejemplo, en código:
process.env.REBROWSER_PATCHES_RUNTIME_FIX_MODE = "alwaysIsolated"
o en la línea de comandos:
REBROWSER_PATCHES_RUNTIME_FIX_MODE=alwaysIsolated node app.js
Por defecto, Puppeteer añade //# sourceURL=pptr:... a cada script en page.evaluate(). Un sitio web remoto puede detectar este comportamiento y levantar banderas rojas.
Este parche lo cambia a //# sourceURL=app.js. También puedes ajustarlo mediante una variable de entorno:
# use any generic filename
REBROWSER_PATCHES_SOURCE_URL=jquery.min.js
# use 0 to completely disable this patch
REBROWSER_PATCHES_SOURCE_URL=0
A veces, podría ser muy útil acceder a una sesión CDP a nivel de navegador. Por ejemplo, cuando quieres implementar algún comando CDP personalizado. Existe un método page._client() que devuelve la sesión CDP para la instancia de página actual, pero no existe tal método para la instancia del navegador.
Este parche añade un nuevo método _connection() a la clase Browser, para que puedas usarlo de esta manera:
browser._connection().on('Rebrowser.addRunEvent', (params) => { ... })
Nota: no es detectable por los scripts de sitios web externos, es solo para tu comodidad.
El nombre del mundo de utilidad predeterminado es '__puppeteer_utility_world__' + packageVersion. A veces podrías querer cambiarlo por otra cosa. Este parche lo cambia a util y te permite personalizarlo mediante una variable de entorno:
REBROWSER_PATCHES_UTILITY_WORLD_NAME=customUtilityWorld
# use 0 to completely disable this patch
REBROWSER_PATCHES_UTILITY_WORLD_NAME=0
Esta variable de entorno no se puede cambiar sobre la marcha; debes establecerla antes de ejecutar tu script porque se utiliza en el momento en que se importa el módulo.
| Antes del parche 👎 | Después del parche 👍 |
|---|---|
![]() |
Nota: no es detectable por los scripts de sitios web externos, pero Google podría usar esta información en su Chrome propietario; nunca lo sabemos.
Este paquete está diseñado para ejecutarse contra una biblioteca instalada. Instala la biblioteca, luego ejecuta el patcher, y listo.
En la carpeta raíz de tu proyecto, ejecuta:
npx rebrowser-patches@latest patch --packageName puppeteer-core
Puedes revertir fácilmente todos los cambios con este comando:
npx rebrowser-patches@latest unpatch --packageName puppeteer-core
También puedes parchear un paquete proporcionando la ruta completa a su carpeta, por ejemplo:
npx rebrowser-patches@latest patch --packagePath /web/app/node_modules/puppeteer-core-custom
Puedes ver todas las opciones de línea de comandos ejecutando npx rebrowser-patches@latest --help, pero actualmente solo hay un parche para una biblioteca, así que no necesitas configurar nada.
⚠️ Ten en cuenta que después de ejecutar npm install o yarn install en la carpeta de tu proyecto, podría sobrescribir todos los cambios de los parches. Necesitarás ejecutar el patcher nuevamente para mantener los parches en su lugar.
Si ya tienes tu paquete parcheado y quieres actualizar a la última versión de rebrowser-patches, la forma más fácil sería eliminar node_modules/puppeteer-core, luego ejecutar npm install o yarn install --check-files, y después ejecutar npx rebrowser-patches@latest patch.
Todas estas versiones son solo envoltorios de la versión Node.js de Playwright. Necesitas encontrar la carpeta driver dentro de tu paquete Playwright y ejecutar este parche con --packagePath=$yourDriverFolder/$yourPlatform/package.
✅ Última versión completamente probada: 24.8.1 (publicada el 2025-05-06)
Los parches de Playwright incluyen:
Runtime.enable: modos addBinding y alwaysIsolated.REBROWSER_PATCHES_UTILITY_WORLD_NAME.Importante: el método page.pause() no funciona con la corrección habilitada; necesita más investigación. Puedes simplemente desactivar la corrección por completo mientras depuras usando la variable de entorno REBROWSER_PATCHES_RUNTIME_FIX_MODE=0.
Estos parches funcionan solo para Chrome por ahora. Si realmente quieres usarlo con WebKit o Firefox, por favor abre un nuevo issue.
✅ Última versión completamente probada: 1.52.0 (publicada el 2025-04-17)
rebrowser-puppeteer con puppeteer-extra?Usa el método addExtra, aquí tienes el ejemplo:
// before
import puppeteer from 'puppeteer-extra'
// after
import { addExtra } from 'puppeteer-extra'
import rebrowserPuppeteer from 'rebrowser-puppeteer-core'
const puppeteer = addExtra(rebrowserPuppeteer)
Actualmente estamos desarrollando más parches para mejorar la transparencia de la automatización web, que se publicarán pronto en este repositorio. Por favor, apoya el proyecto haciendo clic en el botón ⭐️ star o watch.
💭 Si tienes ideas, pensamientos o preguntas, no dudes en contactar a nuestro equipo por correo electrónico o usa la sección de issues.
⚠️ Es importante saber que esta corrección por sí sola no hará que tu navegador sea a prueba de balas e indetectable. Necesitas abordar muchos otros aspectos, como proxies, un user-agent adecuado y huellas digitales (canvas, WebGL), entre otros.
Ten siempre presente: cuanto menos manipules los componentes internos del navegador mediante inyecciones de JS, mejor. Hay formas de detectar que objetos internos como console, navigator y otros fueron afectados por objetos Proxy u Object.defineProperty. Es complicado, pero siempre es un juego del gato y el ratón.
Si has probado de todo y aún enfrentas problemas, intenta hacer una pregunta en la sección de issues o considera usar las soluciones en la nube de Rebrowser.
Este paquete está patrocinado y mantenido por Rebrowser. Te permitimos escalar tu automatización de navegador y web scraping en la nube con cientos de huellas digitales únicas.
Nuestros navegadores en la nube tienen excelentes tasas de éxito e incluyen funciones interesantes, como notificaciones si tu biblioteca usa Runtime.Enable durante la ejecución o tiene otras banderas rojas que podrían mejorarse. Crea una cuenta hoy para recibir una invitación a probar nuestra plataforma de vanguardia y llevar tu negocio de automatización al siguiente nivel.
Cuando intentas ejecutar este patcher en una máquina Windows, probablemente encontrarás un error porque el comando patch no se encuentra. Para solucionarlo, necesitas instalar Git, que incluye patch.exe. Después de instalarlo, debes añadirlo a tu PATH:
set PATH=%PATH%;C:\Program Files\Git\usr\bin\
Puedes comprobar que patch.exe está instalado correctamente usando el siguiente comando:
patch -v
zfcsoftware/puppeteer-real-browser - ideas generales y contribución a la comunidad de automatización
Kaliiiiiiiiii-Vinyzu/patchright - conjunto de parches para corregir fugas de Playwright
kaliiiiiiiiii/brotector - algunas pruebas modernas, algoritmo para distinguir CDP de devtools
prescience-data/harden-puppeteer - uno de los pioneros de la ejecución en un mundo aislado
puppeteer-extra-plugin-stealth - donde todo comenzó, grandes reconocimientos a todos los colaboradores y a la comunidad 🙏 berstend y compañía son los mejores