Se actualizó el modo sin interfaz gráfica de Chrome: la presentación de --headless=new

Mejoramos mucho el modo sin interfaz gráfica de Chrome.

Peter Kvitek
Peter Kvitek

Mejoramos mucho el modo sin interfaz gráfica de Chrome. En este artículo, se presenta una descripción general de los esfuerzos de ingeniería recientes para lograr que Headless sea más útil para los desarrolladores, ya que se acerca al modo "head" normal de Chrome.

Información general

En 2017, Chrome 59 presentó el llamado modo sin interfaz gráfica, que te permite ejecutar el navegador en un entorno sin actividad y sin ninguna IU visible. Básicamente, ejecutar Chrome sin Chrome.

El modo sin interfaz gráfica es una opción popular para la automatización de navegadores con proyectos como Puppeteer o ChromeDriver. A continuación, se muestra un ejemplo de línea de comandos mínimo del uso del modo sin interfaz gráfica para crear un archivo PDF de una URL determinada:

chrome --headless --print-to-pdf https://developer.chrome.com/

Novedades de Headless

Antes de sumergirnos en las mejoras recientes de Headless, es importante comprender cómo funcionaba la versión "antigua" Headless. El fragmento de la línea de comandos que mostramos antes utiliza la marca de línea de comandos --headless, lo que sugiere que Headless es solo un modo de funcionamiento del navegador Chrome normal. Sorprendentemente, no era verdad. Técnicamente, el anterior Headless (sin interfaz gráfica) era una implementación independiente y alternativa de navegador que se enviaba como parte del mismo objeto binario de Chrome. No comparte ningún código del navegador Chrome en //chrome.

Como puedes imaginar, la implementación y el mantenimiento de este navegador Headless independiente conllevaba una gran sobrecarga de ingeniería, pero no fue el único problema. Dado que Headless era una implementación independiente, tenía sus propios errores y funciones que no estaban presentes en la versión ingeniosa de Chrome. Esto creaba una situación confusa en la que cualquier prueba automatizada del navegador podía pasar en el modo cabezal, pero fallar en el modo sin interfaz gráfica, o viceversa, un problema importante para los ingenieros de automatización. También excluyó las pruebas automatizadas que dependían de, por ejemplo, tener instalada una extensión del navegador. Lo mismo ocurre con cualquier otra funcionalidad a nivel del navegador: a menos que Headless tuviera su propia implementación independiente, no era compatible.

En 2021, el equipo de Chrome se dispuso a resolver este problema y unificar los modos Headless y Headless de una vez por todas.

El nuevo Chrome sin interfaz gráfica ya no es una implementación independiente del navegador, sino que ahora comparte código con Chrome.

Nos complace anunciar que el nuevo modo sin interfaz gráfica ya está disponible en Chrome 112. En este modo, Chrome crea ventanas de plataforma, pero no las muestra. Todas las demás funcionalidades, existentes y futuras, están disponibles sin limitaciones.

Prueba la app sin interfaz gráfica

Para probar el nuevo modo sin interfaz gráfica, pasa la marca de línea de comandos --headless=new:

chrome --headless=new

Por el momento, el modo sin interfaz gráfica anterior todavía está disponible en los siguientes dispositivos:

chrome --headless=old

Actualmente, pasar la marca de línea de comandos --headless sin un valor explícito activa el modo Headless anterior, pero, con el tiempo, planeamos cambiar esta configuración predeterminada a la nueva versión sin interfaz gráfica.

Planeamos quitar por completo la versión antigua sin interfaz gráfica del objeto binario de Chrome y dejar de admitir este modo en Puppeteer más adelante este año. Como parte de esta eliminación, la versión anterior estará disponible como objeto binario independiente para los usuarios que aún no puedan realizar la actualización.

Nuevo Headless en Puppeteer

Para habilitar el nuevo modo sin interfaz gráfica en Puppeteer, haz lo siguiente:

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch({
  headless: 'new',
  // `headless: true` (default) enables old Headless;
  // `headless: 'new'` enables new Headless;
  // `headless: false` enables "headful" mode.
});

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

// …

await browser.close();

Nuevo Headless en Selenium-WebDriver

Para usar el nuevo modo sin interfaz gráfica en Selenium-WebDriver, haz lo siguiente:

const driver = await env
  .builder()
  .setChromeOptions(options.addArguments('--headless=new'))
  .build();

await driver.get('https://developer.chrome.com/');

// …

await driver.quit();

Consulta la entrada de blog del equipo de Selenium para obtener más información, incluidos ejemplos con otras vinculaciones de lenguajes.

Marcas de línea de comandos específicas sin interfaz gráfica

Las siguientes marcas de línea de comandos están disponibles para el nuevo modo sin interfaz gráfica.

--dump-dom

La marca --dump-dom imprime el DOM serializado de la página de destino en stdout. Por ejemplo:

chrome --headless=new --dump-dom https://developer.chrome.com/

Ten en cuenta que esto no es lo mismo que imprimir el código fuente HTML (lo que puedes hacer con curl). Para brindarte el resultado de --dump-dom, Chrome primero analiza el código HTML en un DOM, ejecuta cualquier <script> que pueda alterar el DOM y, luego, vuelve a convertirlo en una cadena serializada de HTML.

--screenshot

La marca --screenshot toma una captura de pantalla de la página de destino y la guarda como screenshot.png en el directorio de trabajo actual. Es especialmente útil en combinación con la marca --window-size. Por ejemplo:

chrome --headless=new --screenshot --window-size=412,892 https://developer.chrome.com/

--print-to-pdf

La marca --print-to-pdf guarda la página de destino como un PDF llamado output.pdf en el directorio de trabajo actual. Por ejemplo:

chrome --headless=new --print-to-pdf https://developer.chrome.com/

De forma opcional, puedes agregar la marca --no-pdf-header-footer para omitir el encabezado de impresión (con la fecha y hora actuales) y el pie de página (con la URL y el número de página).

chrome --headless=new --print-to-pdf --no-pdf-header-footer https://developer.chrome.com/

--timeout

La marca --timeout define el tiempo de espera máximo (en milisegundos) después del cual --dump-dom, --screenshot y --print-to-pdf capturan el contenido de la página, incluso si la página aún se está cargando.

chrome --headless=new --print-to-pdf --timeout=5000 https://developer.chrome.com/

La marca --timeout=5000 le indica a Chrome que espere hasta 5 segundos antes de imprimir el PDF. Por lo tanto, este proceso tarda 5 segundos como máximo en ejecutarse.

--virtual-time-budget

--virtual-time-budget te permite viajar en el tiempo. Bueno, hasta cierto punto. El tiempo virtual actúa como un "adelante" para cualquier código que depende del tiempo (por ejemplo, setTimeout/setInterval). Fuerza al navegador a ejecutar cualquier código de la página lo más rápido posible y, al mismo tiempo, hace creer a la página que el tiempo realmente pasa.

Para ilustrar su uso, considera esta página de demostración que incrementa, registra y muestra un contador cada segundo usando setTimeout(fn, 1000). Este es el código relevante:

<output>0</output>
<script>
  const element = document.querySelector('output');
  let counter = 0;
  setInterval(() => {
    counter++;
    console.log(counter);
    element.textContent = counter;
  }, 1_000);
</script>

Después de un segundo, la página contiene "1"; después de dos segundos, "2", y así sucesivamente. Aquí te mostramos cómo capturar el estado de la página después de 42 segundos y guardarlo como PDF:

chrome --headless=new --print-to-pdf --virtual-time-budget=42000 https://mathiasbynens.be/demo/time

--allow-chrome-scheme-url

Se requiere la marca --allow-chrome-scheme-url para acceder a las URLs de chrome://. Esta marca está disponible a partir de Chrome 123. Por ejemplo:

chrome --headless=new --print-to-pdf --allow-chrome-scheme-url chrome://gpu

Depuración

Como Chrome es efectivamente invisible en modo sin interfaz gráfica, puede resultar difícil entender qué está sucediendo en caso de problemas. Afortunadamente, es posible depurar Chrome sin interfaz gráfica de una manera muy similar a la de Chrome. El truco es iniciar Chrome en modo sin interfaz gráfica con la función experimental de línea de comandos --remote-debugging-port.

chrome --headless=new --remote-debugging-port=0 https://developer.chrome.com/

Esto imprime una URL de WebSocket única en stdout, por ejemplo:

DevTools listening on ws://127.0.0.1:60926/devtools/browser/b4bd6eaa-b7c8-4319-8212-225097472fd9

En una instancia normal de Chrome, podemos usar la depuración remota de las Herramientas para desarrolladores de Chrome para conectarnos al destino sin interfaz gráfica e inspeccionarlo. Para hacerlo, ve a chrome://inspect, haz clic en el botón Configurar... y, luego, ingresa la dirección IP y el número de puerto de la URL de WebSocket. En el ejemplo anterior, ingresé 127.0.0.1:60926. Haz clic en Listo. Deberías ver un destino remoto con todas sus pestañas y otros objetivos que se indican a continuación. Haz clic en inspect y, ahora, tendrás acceso a las Herramientas para desarrolladores de Chrome que inspeccionan el destino remoto sin interfaz gráfica, inspect.

Las Herramientas para desarrolladores de Chrome pueden inspeccionar una página de destino sin interfaz gráfica remota

Comentarios

Esperamos recibir tus comentarios sobre el nuevo modo sin interfaz gráfica. Si tienes algún problema, infórmalo.