In a previous occasion , we used Puppeteer to automate clicking a button on a web interface. In this case, we will log in and read some values to verify the correct functioning of the network interfaces of a router. Additionally, if it detects an incorrect speed on any of the ports, it will send us a message via Telegram.
The data we are going to read is marked in red in the screenshot:
You can find the Puppeteer project on Github: https://github.com/puppeteer/puppeteer
Install Node.js:
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:
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:
// 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()
})()
The XPath of web elements can be easily obtained from Chrome:
Inspect element -> Right-click on the element on the right side -> Copy -> Copy XPath
Este script se puede crontabear y así tener un sistema básico de monitorización de la velocidad de los puertos del router:
*/1 * * * * /usr/local/bin/node /home/kr0m/.scripts/routerSpeed/routerSpeed.js