La automatización de acciones en interfaces web es un campo muy interesante, en un artÃculo anterior ya explicamos como hacerlo mediante Python/Selenium, en esta ocasión utilizaremos NodeJS/Puppeteer. El ejemplo hará login en un formulario web y acto seguido clickará sobre un botón determinado.
Podemos encontrar el proyecto en Github: https://github.com/puppeteer/puppeteer
Instalamos nodejs:
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()
})()
NOTA: Se ha intriducido un slowmotion slowMo: 50 para que el comportamiento parezca mas humano y un delay await delay(4000) para que la web cargue por completo antes de realizar el click.
Para probarlo tan solo hay que ejecutarlo del siguiente modo: