Volver al Centro de conocimiento
Primeros pasos

Puppeteer + BotBrowser: errores de lanzamiento y de perfil

Evita los errores de Puppeteer que rompen la coherencia del perfil de BotBrowser: defaultViewport, el Chromium incluido y la sesión CDP de nivel de navegador mal usada.

BotBrowser Team

Documentación

Prefieres la documentación del producto mantenida?

Este artículo tiene una página equivalente en el centro de documentación. Usa los docs para el flujo canónico, las flags actuales y la referencia duradera.

Si quieres la configuración más corta de BotBrowser con Puppeteer, empieza por la página de documentación de Puppeteer. Después del primer lanzamiento correcto, suelen aparecer tres errores de integración que rompen en silencio la coherencia del perfil; sus síntomas permiten reconocer cada uno y corregirlo sin tocar el código de tus páginas.

Puppeteer es una capa de control. Decide qué binario se inicia, qué opciones de lanzamiento se aplican y qué comandos se envían por la conexión de DevTools. BotBrowser es el navegador que carga un perfil y lo presenta a las páginas. Cuando ambos están bien conectados, tus selectores, tu lógica de navegación y tu extracción de datos funcionan igual que antes. Cuando están mal conectados, el perfil puede cargarse y, aun así, algo a su alrededor lo contradice, y esa contradicción es más difícil de diagnosticar que un fallo evidente.

Lista de lanzamiento de Puppeteer para BotBrowser: puppeteer-core inicia el binario de BotBrowser, los comandos CDP usan una sesión de nivel de navegador y defaultViewport vale null

Resumen

  • Inicia puppeteer-core con un executablePath explícito; el Chromium que incluye el paquete puppeteer nunca carga un perfil.
  • Mantén defaultViewport: null; si una página nueva mide 800x600, la sobrescritura de viewport de Puppeteer sigue activa.
  • Envía comandos de BotBrowser como BotBrowser.setCustomHeaders mediante browser.target().createCDPSession(), no con una sesión de página.
  • Coloca --bot-profile, --proxy-server, --bot-timezone, --bot-locale y --bot-languages en args y después compara navigator.languages y screen.width con el perfil.

Contenido

Tres errores de lanzamiento que rompen la coherencia del perfil

La mayoría de las integraciones fallidas de Puppeteer se deben a una de tres causas. Cada una tiene un síntoma distinto, así que conviene reconocerlas por lo que ves y no por lo que configuraste.

  • Se inicia el binario equivocado. El paquete puppeteer normal descarga su propia compilación de Chromium, y un lanzamiento sin executablePath explícito usa esa compilación. El navegador se abre y las páginas cargan, pero ningún perfil de BotBrowser interviene.
  • Puppeteer sobrescribe el viewport. Puppeteer aplica un viewport por defecto de 800x600 a cada página nueva, salvo que desactives ese comportamiento. Un perfil que describe una pantalla más grande queda junto a una página que informa de una ventana pequeña, y las dos cifras se contradicen.
  • Un comando de BotBrowser va a la sesión equivocada. BotBrowser añade sus propios comandos CDP, y están disponibles en la sesión de nivel de navegador. Una sesión de nivel de página no los conoce, así que la llamada falla con un error de método no encontrado.

Ninguno de estos casos produce un fallo evidente. El primero te da un Chromium perfectamente normal, el segundo una página normal con un tamaño de ventana extraño, y el tercero una llamada fallida que es fácil atribuir a una errata. Por eso superan tantas veces la revisión de código.

Coherencia del perfil significa simplemente que los valores que van juntos concuerdan entre sí. Una sesión que informa de una pantalla, un tamaño de ventana, una lista de idiomas y una zona horaria debería informar de combinaciones que encajen. El perfil aporta esos valores, así que cualquier cosa ajena al perfil que cambie uno de ellos, como una opción de Puppeteer o un script olvidado, crea un desacuerdo que el perfil nunca pretendió.

Un buen lanzamiento tiene una firma breve. El proceso que se inicia es el binario de BotBrowser, la ruta del perfil se pasa como argumento de lanzamiento, el viewport por defecto está desactivado y cualquier comando específico de BotBrowser se envía por una sesión creada desde el destino del navegador. Las secciones siguientes recorren esos cuatro puntos y después muestran cómo confirmarlos desde fuera.

Ten presente qué es y qué no es esta lista. Cubre la configuración de lanzamiento: qué binario, qué argumentos, qué comportamiento del viewport y qué sesión. No cambia la forma en que Puppeteer controla las páginas ni afirma nada sobre cómo tratará un sitio concreto la sesión resultante.

Lanza BotBrowser con puppeteer-core

Instala los componentes

La documentación de BotBrowser enumera cuatro requisitos para Puppeteer: un binario de BotBrowser instalado, Node.js 18 o superior, el paquete puppeteer-core y un archivo de perfil. Los entornos de producción usan un perfil .enc cifrado, y el perfil debe corresponder a la versión de BotBrowser que ejecutas.

  • Un binario de BotBrowser, descargado del repositorio de BotBrowser e instalado como indica la guía de instalación.
  • Node.js 18 o superior.
  • El paquete npm puppeteer-core.
  • Un archivo de perfil, normalmente con la extensión .enc.

La elección del paquete importa más de lo que parece. El paquete completo puppeteer incluye la descarga de un navegador, justo lo que no quieres lanzar por accidente. puppeteer-core ofrece la misma API de automatización sin ningún navegador incluido, así que te obliga a indicar qué ejecutable iniciar. Ese requisito es el punto de integración: pasas la ruta del binario de BotBrowser y Puppeteer lo inicia.

npm init -y
npm install puppeteer-core

Un lanzamiento mínimo

El lanzamiento mínimo documentado define cuatro cosas que un script de Puppeteer estándar suele omitir o dejar en sus valores por defecto.

import puppeteer from 'puppeteer-core';

const browser = await puppeteer.launch({
  browser: 'chrome',
  executablePath: process.env.BOTBROWSER_EXEC_PATH,
  headless: true,
  defaultViewport: null,
  args: [`--bot-profile=${process.env.BOT_PROFILE_PATH}`],
});

const page = await browser.newPage();
await page.goto('https://example.com');
await browser.close();

Cada opción tiene su función.

  • browser: "chrome" selecciona el arranque en modo Chrome, que es lo que pide la documentación de BotBrowser con puppeteer-core. Si un lanzamiento falla dentro de puppeteer-core, esta opción y la ruta del ejecutable son lo primero que debes revisar.
  • executablePath apunta al binario de BotBrowser. Leerlo desde una variable de entorno mantiene las rutas propias de cada máquina fuera del script y hace que el mismo código funcione en un portátil y en un servidor.
  • headless: true se ejecuta sin ventana visible. Desactívalo mientras depuras si quieres ver la sesión.
  • defaultViewport: null desactiva la sobrescritura del viewport de Puppeteer, que se explica en la sección siguiente.
  • args lleva los flags de BotBrowser. --bot-profile carga el perfil, y una ruta absoluta evita sorpresas cuando el directorio de trabajo cambia entre máquinas.

El código de página posterior a la llamada de lanzamiento es Puppeteer corriente. Nada de newPage, goto, los selectores o close es específico de BotBrowser, y ese es el objetivo: migrar un proyecto existente solo debería tocar el bloque de lanzamiento.

Por qué defaultViewport debe ser null

La referencia de opciones de lanzamiento de Puppeteer describe defaultViewport como el ajuste que da a cada página un viewport coherente, con un valor por defecto de 800x600. Al ponerlo en null se desactiva ese valor. En una suite de pruebas normal es una comodidad. Con un perfil de BotBrowser se convierte en un conflicto, porque el perfil ya describe las dimensiones de pantalla y de ventana que la sesión debe informar.

Cuando la sobrescritura sigue activa, Puppeteer ajusta cada página a 800x600 después de que el navegador haya cargado el perfil. El perfil dice una cosa y la página mide otra. Cualquiera que compare las dimensiones de pantalla con las dimensiones internas de la ventana verá una combinación que ningún dispositivo real produce. Es la razón más común por la que una primera prueba parece incorrecta aunque el perfil se haya cargado sin errores.

La corrección es una sola línea y el síntoma es fácil de confirmar: si la ventana interna de una página nueva mide 800x600, el viewport por defecto sigue activo. Define defaultViewport: null, vuelve a lanzar y la página tomará sus dimensiones del perfil. Mantén esa línea en cada llamada de lanzamiento que escribas, incluidos los scripts que copies de ejemplos antiguos de Puppeteer, porque casi todos dependen del valor por defecto.

Migra un proyecto existente

Un proyecto de Puppeteer existente necesita tres cambios, y los tres ocurren en el bloque de lanzamiento. Sustituye la dependencia puppeteer por puppeteer-core, de modo que no se descargue ningún navegador incluido y cada lanzamiento tenga que indicar su ejecutable. Sustituye las opciones de lanzamiento por el lanzamiento mínimo mostrado arriba, con la ruta del binario de BotBrowser y la ruta del perfil. Después elimina cualquier valor de defaultViewport y sé prudente con las llamadas explícitas de viewport, porque dimensionar una página a mano sobrescribe esas mismas dimensiones del perfil.

Todo lo que viene después del bloque de lanzamiento se queda como está: navegación, esperas, selectores, extracción de datos, capturas y limpieza. Si un proyecto tiene varios puntos de lanzamiento, como uno en un helper de pruebas y otro en una herramienta independiente, actualiza cada uno. Basta un lanzamiento olvidado con la configuración antigua para recuperar el navegador incluido o la sobrescritura del viewport.

Cierra lo que lanzas. Cada llamada a puppeteer.launch inicia un proceso de navegador independiente, así que envuelve el trabajo en try y finally y llama a browser.close() en el bloque finally; de lo contrario, una ejecución fallida deja un proceso atrás.

Mantén los valores propios de cada máquina fuera del código fuente. La ruta del binario, la ruta del perfil y las credenciales del proxy funcionan bien como variables de entorno, como en los ejemplos anteriores, porque así el mismo script se ejecuta sin cambios en un portátil, en un runner de CI y en un servidor, y las credenciales no entran en el control de versiones.

Envía comandos CDP de BotBrowser por una sesión de nivel de navegador

Puppeteer expone el Chrome DevTools Protocol mediante objetos CDPSession. Los comandos estándar del protocolo funcionan en cualquier sesión. Los comandos propios de BotBrowser, como BotBrowser.setCustomHeaders, pertenecen al navegador en conjunto, por lo que están disponibles en una sesión asociada al destino del navegador.

const cdp = await browser.target().createCDPSession();

await cdp.send('BotBrowser.setCustomHeaders', {
  headers: { 'x-client-app': 'bb' },
});

La llamada que hay que mirar es browser.target().createCDPSession(). Crea una sesión sobre el propio navegador. La más conocida page.createCDPSession() crea una sesión sobre un único destino de página, y esa sesión no reconoce los comandos de BotBrowser. El resultado es un error de método no encontrado que parece una errata en el nombre del comando, incluso cuando el nombre es exactamente el correcto.

Cuando veas ese error, comprueba de dónde viene la sesión antes de revisar la ortografía. Si la sesión viene de una página, crea una nueva desde el destino del navegador y vuelve a enviar el comando. Una sola sesión de nivel de navegador basta para todo el script, así que puedes crearla una vez tras el lanzamiento y reutilizarla para cada comando de BotBrowser.

Dar nombres claros hace visible el alcance en la revisión de código. Una variable llamada browserCdp, creada desde browser.target(), es difícil de confundir con una sesión de página, mientras que una variable genérica llamada client, creada dentro de un helper de página, es fácil de usar mal meses después por alguien que no la escribió.

Las funciones estándar de Puppeteer siguen su camino normal. Solo los comandos específicos de BotBrowser necesitan la sesión de nivel de navegador, y el resto del script sigue usando los métodos habituales de página.

Añade ajustes de proxy, zona horaria e idioma

Un perfil describe un dispositivo. Los ajustes de red y de región describen dónde parece estar ese dispositivo. La documentación de BotBrowser pasa ambos tipos de ajustes mediante args, junto a --bot-profile.

const browser = await puppeteer.launch({
  browser: 'chrome',
  executablePath: process.env.BOTBROWSER_EXEC_PATH,
  headless: true,
  defaultViewport: null,
  args: [
    `--bot-profile=${process.env.BOT_PROFILE_PATH}`,
    '--proxy-server=socks5://user:[email protected]:1080',
    '--bot-timezone=Asia/Tokyo',
    '--bot-locale=ja-JP',
    '--bot-languages=ja-JP,ja,en-US,en',
  ],
});

Pasa el proxy como --proxy-server dentro de args. BotBrowser acepta credenciales dentro de la URL del proxy, y la documentación desaconseja los patrones de autenticación de proxy exclusivos del framework, porque los valores geográficos derivados de la dirección de salida no encajarán si el proxy se configura fuera del navegador. Si la zona horaria no coincide con la región del proxy, revisa cómo se configuró el proxy antes de mirar cualquier otra cosa; Configuración de proxy detalla las formas de credenciales y de sintaxis.

Con un proxy definido, el comportamiento por defecto documentado es que BotBrowser deriva la zona horaria, la configuración regional y los idiomas de la dirección de salida del proxy. Los flags explícitos --bot-timezone, --bot-locale y --bot-languages sustituyen esos valores derivados en los ajustes que definen. Úsalos cuando quieras una región fija y omítelos cuando quieras que los valores sigan al proxy. Varios de estos flags pertenecen a niveles superiores de BotBrowser, así que consulta la referencia de flags de la CLI para ver qué nivel se aplica a tu configuración antes de depender de ellos.

Si ejecutas varios navegadores desde una misma máquina, da a cada uno su propio --user-data-dir. La documentación recoge los conflictos entre instancias como un problema conocido y el directorio único como la solución, porque mantiene separados el almacenamiento y el estado de sesión.

El proxy por contexto mediante browser.createBrowserContext() merece una lectura atenta de tus versiones. Que ahí se acepte una opción de proxy depende de la versión de Puppeteer y del nivel de BotBrowser, así que trátalo como algo que debes probar en tu propia configuración y no como algo que toda combinación admite.

Verifica el lanzamiento y resuelve los fallos habituales

La verificación debe hacerse desde el lado de la página, porque es lo que ve un sitio web. Abre una página, lee unos pocos valores y compáralos con el perfil que cargaste.

const page = await browser.newPage();
await page.goto('https://example.com');

const reported = await page.evaluate(() => ({
  userAgent: navigator.userAgent,
  languages: navigator.languages,
  screenWidth: screen.width,
  screenHeight: screen.height,
  innerWidth: window.innerWidth,
  innerHeight: window.innerHeight,
  pixelRatio: window.devicePixelRatio,
}));

console.log(reported);

Lee la salida en tres pasos. El user agent y la lista de idiomas deben coincidir con lo que describen el perfil y tus flags regionales. Las dimensiones de pantalla deben coincidir con la pantalla del perfil. Las dimensiones internas de la ventana deben ser coherentes con esa pantalla y no ser exactamente 800x600. Si son 800x600, vuelve al bloque de lanzamiento y busca la sobrescritura del viewport.

Este fragmento es una comprobación de cordura para tu propia integración, no una suite de pruebas ni una promesa sobre ningún sitio. Compara la salida con el perfil que cargaste, no con tu propia máquina. El sentido de la comprobación es que los valores provienen del perfil, así que una coincidencia perfecta con el equipo anfitrión sería un motivo para mirar de nuevo. Ejecútalo una vez después de cambiar el bloque de lanzamiento y otra vez cuando muevas el script a otra máquina, ya que una ruta de binario distinta o un ejemplo copiado es por donde entran la mayoría de las regresiones.

Cuando algo no cuadra, el síntoma suele señalar directamente la causa.

SíntomaCausa probable y solución
El viewport mide 800x600El viewport por defecto está activo. Define defaultViewport: null.
El lanzamiento falla dentro de puppeteer-coreAñade browser: "chrome" y confirma que executablePath apunta al binario de BotBrowser.
El perfil no parece aplicarsePuede haberse iniciado el binario equivocado. Confirma la ruta del ejecutable y usa una ruta absoluta para el perfil.
Los comandos de BotBrowser devuelven método no encontradoLa sesión vino de una página. Créala con browser.target().createCDPSession().
La zona horaria o los idiomas no coinciden con el proxyPasa el proxy mediante --proxy-server en args, no con una opción exclusiva del framework.
Varias instancias se interfieren entre síDa a cada instancia un --user-data-dir único.

Si el perfil no parece aplicarse en absoluto, trabaja de fuera hacia dentro; las combinaciones de flags que usan estos ejemplos están reunidas en las recetas de CLI. Confirma que el proceso que iniciaste es el binario de BotBrowser y no un Chromium estándar, confirma que la ruta del perfil es absoluta y que el archivo existe, y confirma que el paquete de perfil corresponde a la versión principal de BotBrowser que instalaste, porque la documentación pide versiones que coincidan. Cambia una sola cosa cada vez y vuelve a lanzar, para saber qué cambio fue el que importó.

Una última pregunta frecuente es si siguen haciendo falta plugins que parchean la página desde JavaScript. No forman parte de la configuración documentada de BotBrowser. El perfil lo aplica el binario del navegador que lanzas, y la lista de lanzamiento anterior no depende de parches a nivel de página. Añadirlos te da una capa más que analizar cuando un lanzamiento se ve mal, así que prueba primero la configuración documentada y añade cualquier otra cosa solo por un motivo que sepas nombrar.

Demostrar que los valores vienen del perfil y no del equipo

Comparar los valores declarados con tu propia máquina responde a la pregunta equivocada. Una sesión que arrancó en silencio un Chromium normal informa los valores del equipo, y un lanzamiento correcto también puede quedar cerca de ellos si el perfil se generó para un dispositivo parecido. Ninguno de los dos resultados indica si el perfil se aplicó.

La comprobación que sí lo responde usa dos perfiles. Ejecuta el mismo script dos veces, carga un perfil distinto en cada ejecución e imprime los mismos campos. Mantén todo lo demás idéntico: la misma ruta del ejecutable, el mismo ajuste de ventana gráfica y la misma página.

// launch-report.mjs: ejecuta una vez por perfil y guarda cada salida
const fields = await page.evaluate(() => ({
  ua: navigator.userAgent,
  langs: navigator.languages.join('|'),
  screen: `${screen.width}x${screen.height}`,
  inner: `${window.innerWidth}x${window.innerHeight}`,
  dpr: window.devicePixelRatio,
}));
console.log(JSON.stringify(fields));
BOT_PROFILE_PATH=/path/profile-a.enc node launch-report.mjs > a.json
BOT_PROFILE_PATH=/path/profile-b.enc node launch-report.mjs > b.json
diff a.json b.json

Tres resultados, tres problemas distintos.

ResultadoQué significaSiguiente paso
diff muestra los campos distintosAmbos perfiles se cargaron y los valores siguen al perfilNo hay nada que corregir en el lanzamiento
diff no imprime nadaNingún perfil llegó al navegadorConfirma executablePath y que el proceso iniciado sea el binario de BotBrowser
Solo cambia ua; screen e inner coincidenSigue activo el ajuste de ventana gráfica, o ambos perfiles describen la misma pantallaRevisa defaultViewport: null y después compara los campos de pantalla del perfil
ua idéntico pero falta un campo propio del perfilEl archivo del perfil no se cargó o no coincide con la versión mayor del binarioContrasta el paquete del perfil con la versión mayor instalada de BotBrowser

La comparación entre dos perfiles es barata: no necesita un sitio de destino ni red más allá de una página en blanco. Ejecútala la primera vez que conectes Puppeteer y de nuevo cada vez que el script apunte a un binario nuevo o a un ejemplo copiado, porque son los dos puntos donde la configuración de lanzamiento cambia sin que nadie lo note.

Si la comparación no imprime nada, deja de depurar la página. Ningún newPage, goto ni selector hace que un perfil se aplique; esa decisión ya se tomó dentro de la llamada de lanzamiento.

Qué cubre BotBrowser y qué no

BotBrowser documenta el lanzamiento de Puppeteer mediante puppeteer-core con browser en chrome, un executablePath, --bot-profile y defaultViewport: null, de modo que las dimensiones de viewport del perfil siguen siendo las que mandan en lugar del valor por defecto de 800x600 de Puppeteer, y los comandos CDP de BotBrowser se envían por una sesión de nivel de navegador. Para ti, eso significa una receta de lanzamiento breve y comprobable: si una sesión parece incoherente, puedes compararla con estos cuatro puntos y encontrar el que difiere. BotBrowser no puede corregir un lanzamiento que Puppeteer sobrescribe, como un defaultViewport dejado en su valor por defecto, no sustituye una configuración de lanzamiento de Puppeteer correcta y no garantiza cómo trata cualquier sitio de destino la sesión.

Los mismos límites se aplican a los temas vecinos. Los flags de proxy y de región dependen del proxy y de tu nivel de BotBrowser, y la compatibilidad con proxy por contexto depende tanto de la versión de Puppeteer como del nivel. Comparar BotBrowser con plugins que parchean la página solo describe en qué nivel actúa cada enfoque, ya que uno actúa mediante el binario del navegador y el otro mediante JavaScript inyectado. No dice nada sobre cómo reaccionará ningún sitio ante uno u otro.

Para configuraciones relacionadas, lee Primeros pasos con Playwright si también usas Playwright, Recetas de CLI para combinaciones de flags, Configuración de servidor headless para ejecutar en un servidor y Configuración de proxy para la sintaxis del proxy y las credenciales.

Fuentes públicas

Conclusión práctica

Cuatro decisiones de lanzamiento se comprueban antes de ejecutar código de página: executablePath nombra el binario de BotBrowser, --bot-profile apunta a un archivo .enc absoluto que coincide con la versión principal instalada, defaultViewport: null mantiene la sobrescritura de 800x600 de Puppeteer fuera de la página, y los comandos de BotBrowser viajan en la sesión creada desde browser.target(). Ante una sesión que no cuadra, recorre esos cuatro puntos antes de tocar selectores o lógica de navegación. BotBrowser configura el lanzamiento; no corrige una opción que Puppeteer sobrescribe ni decide cómo tratará un sitio de destino la sesión resultante.

#Puppeteer#automatización#primeros pasos#tutorial

Este artículo forma parte de la guía: Primeros pasos con automatización de navegador: mapa inicial

Lleva BotBrowser de la investigación a producción

Usa estas guías para entender el modelo y después avanzar hacia validación multiplataforma, contextos aislados y despliegue de navegador preparado para escalar.