Categorías Programación Etiquetas , ,

Todo sobre Puppeteer: La biblioteca para automatización de navegadores

Puppeteer es una poderosa biblioteca de Node.js desarrollada por el equipo de Google Chrome, diseñada para interactuar con navegadores web de manera programática. Lanzada por primera vez en 2017, Puppeteer ganó popularidad rápidamente en la comunidad de desarrolladores por su capacidad para controlar instancias de Chromium (y más recientemente otros navegadores) con facilidad.

Origen de Puppeteer

Puppeteer fue desarrollado como parte del equipo de Chrome DevTools en Google, con el objetivo de proporcionar a los desarrolladores una herramienta más accesible y eficiente para la automatización de navegadores. Antes de Puppeteer, herramientas como Selenium dominaban el espacio de la automatización de navegadores, pero Puppeteer se destacó rápidamente gracias a su API moderna, fácil de usar y completamente escrita en JavaScript, lo que permite una integración fluida con las aplicaciones Node.js.

¿Para qué sirve Puppeteer?

Puppeteer se utiliza en una amplia variedad de casos, algunos de los más comunes incluyen:

Automatización de pruebas: Puppeteer permite a los desarrolladores escribir pruebas automáticas para interfaces de usuario. Esto es especialmente útil en aplicaciones web donde es necesario verificar el comportamiento de los elementos de la página después de interacciones complejas.

Scraping de datos: Con Puppeteer, es posible extraer información de sitios web dinámicos que se cargan a través de JavaScript, algo que suele ser un desafío con otras herramientas de scraping más simples.

Generación de PDFs: Puppeteer puede convertir páginas web en archivos PDF, lo que es útil para generar informes, recibos u otros documentos a partir de contenido web.

Captura de pantallas: Los desarrolladores pueden capturar capturas de pantalla de páginas web completas o de elementos específicos, lo cual es útil para la creación de vistas previas, la detección de errores visuales o la monitorización de contenido.

Automatización de tareas repetitivas: Puppeteer es capaz de automatizar tareas repetitivas que normalmente requerirían interacción humana, como rellenar formularios, realizar búsquedas o interactuar con elementos de una página.

Instalación de Puppeteer

Instalar Puppeteer es un proceso sencillo que se puede realizar a través de npm, el gestor de paquetes de Node.js. Para instalar Puppeteer, simplemente hay que abrir una terminal y ejecutar el siguiente comando:

npm install puppeteer

Este comando descargará e instalará Puppeteer junto con una versión compatible de Chromium, que es el navegador con el que Puppeteer interactúa por defecto. La descarga de Chromium puede hacer que la instalación ocupe varios cientos de megabytes, así que hay que asegurarse de tener suficiente espacio disponible.

Principales propiedades de Puppeteer

Puppeteer ofrece una gran cantidad de propiedades y configuraciones que permiten a los desarrolladores personalizar su comportamiento. A continuación, vamos a ver algunas de las propiedades más relevantes, acompañadas de ejemplos de cómo se utilizan.

1. Headless

La propiedad headless es quizás la más conocida de Puppeteer. Cuando Puppeteer se ejecuta en modo «headless» (sin cabeza), el navegador se ejecuta sin una interfaz gráfica de usuario (GUI), lo que significa que todas las interacciones ocurren en segundo plano. Esto es ideal para la mayoría de los casos de automatización donde la velocidad y la eficiencia son clave.

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({ headless: true });
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await page.screenshot({ path: 'example.png' });
  await browser.close();
})();

En este ejemplo, Puppeteer toma una captura de pantalla del sitio web example.com sin mostrar una ventana del navegador.

2. Sandbox

El modo sandbox es una configuración de seguridad que aísla procesos y reduce los riesgos de seguridad en caso de que algo salga mal. Sin embargo, en ciertos entornos, puede ser necesario deshabilitar el sandboxing, como cuando se ejecuta Puppeteer en contenedores Docker.

const browser = await puppeteer.launch({
  args: ['--no-sandbox', '--disable-setuid-sandbox']
});

Esta configuración desactiva el sandboxing, permitiendo a Puppeteer ejecutarse en entornos más restringidos.

3. SlowMo

La propiedad slowMo es útil para depurar scripts de automatización. Al usar slowMo, puede ralentizar las acciones de Puppeteer para observar más claramente lo que sucede en cada paso.

const browser = await puppeteer.launch({ headless: false, slowMo: 100 });

En este caso, cada acción que Puppeteer realiza se ralentizará en 100 ms, lo que facilita la observación de lo que sucede en la interfaz del navegador.

4. DefaultViewport

Puppeteer permite especificar el tamaño de la ventana del navegador mediante la propiedad defaultViewport. Esto es útil cuando necesitamos simular diferentes dispositivos o tamaños de pantalla.

const browser = await puppeteer.launch({
  defaultViewport: { width: 1280, height: 800 }
});

Este ejemplo configura el navegador para que tenga un tamaño de ventana de 1280×800 píxeles.

5. ExecutablePath

La propiedad executablePath permite especificar la ruta al ejecutable de un navegador diferente al Chromium predeterminado. Esto es útil si deseamos usar Puppeteer con Chrome, Firefox, o cualquier otro navegador basado en Chromium.

const browser = await puppeteer.launch({
  executablePath: '/path/to/your/chrome'
});

6. Args

La propiedad args permite pasar un array de argumentos adicionales a la instancia del navegador que se está lanzando. Esto es útil cuando necesitamos ajustar configuraciones del navegador o habilitar/deshabilitar características específicas.

const browser = await puppeteer.launch({
  args: ['--disable-web-security', '--user-agent="Custom User Agent"']
});

En este ejemplo, --disable-web-security desactiva la seguridad web (útil para evitar problemas con CORS en ciertos escenarios), y --user-agent cambia el agente de usuario que se envía con cada solicitud.

7. IgnoreHTTPSErrors

La propiedad ignoreHTTPSErrors permite que Puppeteer ignore los errores de certificados HTTPS, lo cual es útil cuando se trabaja en entornos de desarrollo con certificados autofirmados.

const browser = await puppeteer.launch({
  ignoreHTTPSErrors: true
});

Este ejemplo hace que Puppeteer ignore cualquier error de HTTPS, habilitando la navegación en sitios con certificados no confiables.

8. UserDataDir

La propiedad userDataDir permite especificar un directorio en el cual se almacenan los datos del usuario (cookies, sesión, cache, etc.). Esto es útil para mantener la persistencia de la sesión entre ejecuciones de Puppeteer.

const browser = await puppeteer.launch({
  userDataDir: './my-user-data'
});

Este ejemplo almacena los datos del usuario en el directorio ./my-user-data, permitiendo que el estado de la sesión se conserve entre diferentes ejecuciones.

9. Timeout

La propiedad timeout define el tiempo máximo (en milisegundos) que Puppeteer esperará para lanzar el navegador antes de abortar la operación. Esto es útil para controlar mejor el flujo de ejecución, especialmente en entornos donde la latencia es un factor crítico.

const browser = await puppeteer.launch({
  timeout: 30000
});

En este ejemplo, Puppeteer esperará hasta 30 segundos antes de detener el intento de lanzamiento del navegador si algo va mal.

10. Devtools

La propiedad devtools permite abrir automáticamente las DevTools de Chrome (herramientas de desarrollo) cuando Puppeteer inicia el navegador. Esto es especialmente útil para depuración avanzada, permitiéndonos inspeccionar elementos, revisar la consola del navegador, y mucho más.

const browser = await puppeteer.launch({
  devtools: true
});

Este ejemplo abre las DevTools automáticamente al lanzar el navegador, proporcionando una vista detallada de lo que ocurre durante la ejecución del script.

Cómo crear un PDF con Puppeteer

Puppeteer ofrece una función muy útil para generar PDFs a partir de páginas web. Esta funcionalidad es particularmente valiosa para crear reportes, facturas, recibos u otros documentos que se basan en contenido web. La función de PDF en Puppeteer permite capturar una representación exacta de una página web y convertirla en un archivo PDF, con una amplia gama de opciones de personalización.

Veamos un ejemplo básico de cómo utilizar Puppeteer para generar un PDF a partir de una página web

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com', { waitUntil: 'networkidle2' });
  
  await page.pdf({
    path: 'example.pdf', // Ruta donde se guardará el archivo PDF
    format: 'A4', // Formato del papel
    printBackground: true // Incluye los fondos de la página en el PDF
  });

  await browser.close();
})();

Explicación de las Opciones de PDF

path: Especifica la ruta y el nombre del archivo PDF que se generará. Si no se especifica un path, el archivo PDF se devolverá como un Buffer que puede manejarse directamente en el código.

format: Define el tamaño del papel para el PDF. Puppeteer soporta varios formatos predefinidos como A4, A3, Letter, etc.

printBackground: Si se establece en true, Puppeteer incluirá los colores de fondo y las imágenes de fondo en el PDF generado. Por defecto, está deshabilitado.

Cómo hacer Web Scraping de precios de un producto

Para ilustrar el poder de Puppeteer, veamos un ejemplo más avanzado de web scraping. Imaginemos que queremos extraer el precio de un producto de un sitio web de comercio electrónico.

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({ headless: true });
  const page = await browser.newPage();
  await page.goto('https://www.example.com/product-page');

  const productDetails = await page.evaluate(() => {
    const price = document.querySelector('.price-tag').innerText;
    const title = document.querySelector('.product-title').innerText;
    return { price, title };
  });

  console.log(`Product: ${productDetails.title}`);
  console.log(`Price: ${productDetails.price}`);

  await browser.close();
})();

En este script, Puppeteer abre la página de un producto, extrae el precio y el título del producto utilizando selectores CSS, y luego imprime esos valores en la consola.

Desde crear un PDF a partir de contenido web hasta hacer Web Scraping de precios de un producto, las posibilidades de esta biblioteca son muchas.