Hamburger Icon
Introducción a Puppeteer en Node.js

Introducción a Puppeteer en Node.js

Puppeteer es un paquete de Node que permite interactuar con un navegador Chrome o Chromium mediante código. La mayoría de cosas que podemos hacer en un navegador de forma manual, las podemos hacer también con Puppeteer.

Para automatizar algunas tareas como el testing de la interfaz puede ser muy útil. Otras cosas que podemos hacer, según se comenta en la documentación oficial, es por ejemplo generar capturas de pantalla, scraping de sitios web, automatizar el envío de formularios o probar extensiones de Chrome.

Instalación

Tienes dos opciones, la instalación normal o la ligera. Por defecto harás lo siguiente:

npm i puppeteer

Esta es la instalación normal, lo cual descarga una versión reciente de Chromium con un peso que puede acercarse a los 300MB. Si necesitas ejecutar tu script en un entorno como AWS Lambda, entonces te puede ser más útil la instalación ligera:

npm install puppeteer-core

Con la instalación ligera ten en cuenta que es necesario que en el entorno haya una instalación de Chrome o Chromium. Siguiendo con el ejemplo de AWS Lambda, sería posible usar chrome-aws-lambda.

Cómo se usa Puppeteer

Si por lo que sea no tienes claro qué es una promesa (o su abstracción con async/await) puedes revisar este tutorial sobre asincronía en JavaScript. Es importante entender esto para comprender el código de los siguientes ejemplos.

Los pasos a seguir son tres: crear una instancia de Browser, abrir una página y manipularla con la API de Puppeteer. Veamos el ejemplo más básico que podemos encontrar en su documentación, crear una captura de pantalla:

const puppeteer = require("puppeteer")

// función que guarda una captura de pantalla
const saveScreenshot = async () => {
  // creamos la instancia del navegador
  const browser = await puppeteer.launch()

  // creamos una nueva página
  // esto sería una pestaña, podemos abrir múltiples
  const page = await browser.newPage()

  // abrimos un sitio web con goto
  await page.goto("https://zeppelin.dev/")

  // guardamos la captura con el comando screenshot
  await page.screenshot({ path: "captura.png" })

  // cerramos la instancia del navegador
  await browser.close()
}

// llamamos a la función para guardar captura
await saveScreenshot()

Veamos otro ejemplo. Vamos a hacer login en algún panel de control, con lo que probaremos el envío de un formulario web. Para hacerlo supondremos que en la página de login del panel hay dos inputs con los identificadores #user y #password y un botón para hacer login con el identificador #login.

const puppeteer = require("puppeteer")

const loginMyPanel = async () => {
  const browser = await puppeteer.launch()
  const page = await browser.newPage()

  await page.goto("https://zeppelin.dev/private")

  // rellenamos los datos en los inputs del formulario de login
  await page.type("#user", "mi_usuario")
  await page.type("#password", "Micontraseña123")

  // con Promise.all() esperamos hasta que terminen
  // los dos eventos, el click y la carga de la
  // siguiente página
  await Promise.all([page.click("#login"), page.waitForNavigation()])

  await browser.close()
}

await loginMyPanel()

Hemos usado la función type() para rellenar los datos del formulario y es importante también la función waitForNavigation(), que nos permite esperar hasta que cargue la página.

Finalmente, otro ejemplo típico es el del scraping. Imagina que en una página concreta tienes este HTML:

<ul id="#myList">
  <li>Elemento 1</li>
  <li>Elemento 2</li>
  <li>Elemento 3</li>
</ul>

Si queremos capturar el texto de la lista, podemos usar la función evaluate, que nos permitirá interactuar con el DOM de la página que tengamos abierta.

const puppeteer = require("puppeteer")

const scrapMyPage = async () => {
  const browser = await puppeteer.launch()
  const page = await browser.newPage()

  await page.goto("https://zeppelin.dev/lists")

  const elements = await page.evaluate(() => {
    // aquí podemos interactuar con el DOM de la página
    const listElements = document.getElementById("myList").childNodes
    const result = listElements.map((item) => item.textContent)

    return result
  })

  console.log(elements) // ["Elemento 1", "Elemento 2", "Elemento 3"]

  await browser.close()
}

await scrapMyPage()

¿Te parece interesante? Seguro que se te viene a la mente alguna tarea repetitiva que podrías automatizar con alguno de estos trucos. Gracias a Puppeteer podemos hacer estas cosas y mucho más. Para más información revisa su documentación para ver la infinidad de métodos que puedes usar.