Esta pagina se ve mejor con JavaScript habilitado

Comprobar valor web con NodeJS/Puppeteer

 ·  🎃 kr0m

En una ocasión anterior ya utilizamos Puppeteer para automatizar el click de un botón en una interfaz web, en este caso vamos a hacer login y leer unos valores para comprobar el correcto funcionamiento de las interfaces de red de un router, además si detecta una velocidad incorrecta en alguno de los puertos nos enviará un mensaje por Telegram.

Los datos que vamos a leer son los marcados en rojo en la captura de pantalla:

Podemos encontrar el proyecto de Puppeteer en Github: https://github.com/puppeteer/puppeteer

Instalamos nodejs:

pkg install npm-node17
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

Instalamos la librería de envío de mensajes a través de Telegram:

npm install simple-telegram-message

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:

vi routerSpeed.js

// npm install simple-telegram-message
const { sendMessageFor } = require('simple-telegram-message')
//const sendMessage = sendMessageFor(process.env.TELEGRAM_TOKEN, 'user_id|channel_id')
const sendMessage = sendMessageFor('345555217:AAgr5t1d5567NgjghCfCGfdrCN56hjGGt5', '12345678')

// PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true npm install puppeteer
const puppeteer = require('puppeteer');

function delay(time) {
    return new Promise(function(resolve) {
        setTimeout(resolve, time)
    });
}

(async () => {
    //const browser = await puppeteer.launch({headless: false, executablePath: '/usr/local/bin/chrome'})
    const browser = await puppeteer.launch({headless: true, executablePath: '/usr/local/bin/chrome'})
  
    const page = await browser.newPage()
    
    const navigationPromise = page.waitForNavigation()
    await page.goto('http://192.168.X.X/login')
    
    await page.setViewport({ width: 1022, height: 1025 })
    
    await navigationPromise
  
    console.log('>> Making login');

    await page.waitForSelector('#username')
    await page.click('#username')
    await page.type('#username', 'USERNAME')
    
    
    await page.waitForSelector('#userpassword')
    await page.click('#userpassword')
    await page.type('#userpassword', 'PASSWORD')
    
    await page.waitForSelector('.form-login > div > .btnbox > #loginBtn > span')
    await page.click('.form-login > div > .btnbox > #loginBtn > span')

    console.log('>> Waiting for page');
    await delay(10000)

    console.log('>> Accessing system information page');

    await page.waitForSelector('.row > #card_sys > .card > #card_sysinfo > .fa-2x')
    await page.click('.row > #card_sys > .card > #card_sysinfo > .fa-2x')

    console.log('>> Waiting for page');
    await delay(9000)

    console.log('>> Reading port speed values');

    let [element0] = await page.$x('//*[@id="popup"]/div/div[2]/div/div[1]/div[2]/ul/li[1]/span[3]');
    let text0 = await page.evaluate(element => element.textContent, element0);
    //console.log('LAN Speed0: ' + text0);
    if (text0 == '-') {
        console.log('LAN Speed0: NO LINK');
    } else if (text0 == '1000M/Full') {
        console.log('LAN Speed0: ' + text0);
    } else {
        console.log('Wrong LAN Speed0: ' + text0);
        sendMessage('Router: Wrong LAN Speed0: ' + text0);
    }

    let [element1] = await page.$x('//*[@id="popup"]/div/div[2]/div/div[1]/div[2]/ul/li[2]/span[3]');
    let text1 = await page.evaluate(element => element.textContent, element1);
    //console.log('LAN Speed1: ' + text1);
    if (text1 == '-') {
        console.log('LAN Speed1: NO LINK');
    } else if (text1 == '1000M/Full') {
        console.log('LAN Speed1: ' + text1);
    } else {
        console.log('LAN Speed1: ' + text1);
        sendMessage('Router: Wrong LAN Speed1: ' + text1);
    }

    let [element2] = await page.$x('//*[@id="popup"]/div/div[2]/div/div[1]/div[2]/ul/li[3]/span[3]');
    let text2 = await page.evaluate(element => element.textContent, element2);
    //console.log('LAN Speed2: ' + text2);
    if (text2 == '-') {
        console.log('LAN Speed2: NO LINK');
    } else if (text2 == '1000M/Full') {
        console.log('LAN Speed2: ' + text2);
    } else {
        console.log('LAN Speed2: ' + text2);
        sendMessage('Router: Wrong LAN Speed2: ' + text2);
    }

    let [element3] = await page.$x('//*[@id="popup"]/div/div[2]/div/div[1]/div[2]/ul/li[4]/span[3]');
    let text3 = await page.evaluate(element => element.textContent, element3);
    //console.log('LAN Speed3: ' + text3);
    if (text3 == '-') {
        console.log('LAN Speed3: NO LINK');
    } else if (text3 == '1000M/Full') {
        console.log('LAN Speed3: ' + text3);
    } else {
        console.log('LAN Speed3: ' + text3);
        sendMessage('Router: Wrong LAN Speed3: ' + text3);
    }

    let [element4] = await page.$x('//*[@id="popup"]/div/div[2]/div/div[1]/div[2]/ul/li[5]/span[3]');
    let text4 = await page.evaluate(element => element.textContent, element4);
    //console.log('WAN Speed: ' + text4);
    if (text4 == '-') {
        console.log('WAN Speed: NO LINK');
    } else if (text4 == '1000M/Full') {
        console.log('WAN Speed: ' + text4);
    } else {
        console.log('Wrong WAN Speed: ' + text4);
        sendMessage('Router: Wrong WAN Speed: ' + text4);
    }

    await browser.close()
  })()

El Xpath de los elementos web se puede conseguir fácilmente desde Chrome:

Inspeccionar elemento -> Botón derecho sobre el elemento en la parte derecha -> Copiar -> Copiar XPath

Este script se puede crontabear y así tener un sistema básico de monitorización de la velocidad de los puertos del router:

crontab -e

*/1 * * * * /usr/local/bin/node /home/kr0m/.scripts/routerSpeed/routerSpeed.js
Si te ha gustado el artículo puedes invitarme a un RedBull aquí