Automating actions on web interfaces is a very interesting field. In a previous article, we explained how to do it using Python/Selenium. This time, we will use NodeJS/Puppeteer. The example will log in to a web form and then click on a specific button.
You can find the project on Github: https://github.com/puppeteer/puppeteer
Install Node.js:
pkg install npm-node12
emerge -av net-libs/nodejs
Instalamos puppeteer como usuario regular, este intentará descargar una copia de Chrome pero en FreeBSD se queja de que no es una plataforma soportada:
Error: Unsupported platform: freebsd
Para solventarlo tan solo debemos instalarlo indicando que no queremos descargar ninguna copia de Chrome, ya que nosotros ya disponemos de una en local instalada por sl sistema operativo:
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true npm install puppeteer
npm install puppeteer
En mi caso utilizo esta extensión de Chrome para crear el script base y a partir de este ir adaptándolo a mis necesidades:
https://chrome.google.com/webstore/detail/puppeteer-recorder/djeegiggegleadkkbgopoonhjimgehda
El script final quedaría del siguiente modo:
const puppeteer = require('puppeteer');
function delay(time) {
return new Promise(function(resolve) {
setTimeout(resolve, time)
});
}
(async () => {
//const browser = await puppeteer.launch({headless: false, slowMo: 50})
//const browser = await puppeteer.launch({headless: true, slowMo: 50})
const browser = await puppeteer.launch({headless: true, slowMo: 50, executablePath: '/usr/local/bin/chrome'})
const page = await browser.newPage()
const navigationPromise = page.waitForNavigation()
await page.goto('URL')
await page.setViewport({ width: 1919, height: 993 })
await navigationPromise
await page.waitForSelector('.card-content > .mat-form-auth > .w-100:nth-child(1) > .mat-form-field-wrapper > .mat-form-field-flex')
await page.click('.card-content > .mat-form-auth > .w-100:nth-child(1) > .mat-form-field-wrapper > .mat-form-field-flex')
await page.type('.w-100 #mat-input-0', 'EMAIL')
await page.waitForSelector('.w-100 #mat-input-1')
await page.click('.w-100 #mat-input-1')
await page.type('.w-100 #mat-input-1', 'PASSWORD')
await page.waitForSelector('.card > .card-content > .mat-form-auth > .float-right > .mat-button-wrapper')
await page.click('.card > .card-content > .mat-form-auth > .float-right > .mat-button-wrapper')
await delay(4000);
await page.waitForSelector('.card-body > .ml-2 > .mat-fab > .mat-button-wrapper > .mat-icon')
await page.click('.card-body > .ml-2 > .mat-fab > .mat-button-wrapper > .mat-icon')
await browser.close()
})()
NOTE: A slow motion slowMo: 50 has been introduced to make the behavior appear more human-like, and a delay await delay(4000) has been added to allow the web to fully load before performing the click.
To test it, simply execute it as follows: