Leggere una variabile da pagina html

Salve a tutti,
sto cercando di leggere un dato da una pagina html generata da un router 4G collegato al mio arduino YUN. Sto utilizzando la libreria HTTPclient, ho utilizzato un sketch esempio che ho trovato sul forum, ma arduino non riesce a leggere la variabile. Riuscite gentilmente a dirmi il perché?
Grazie

/*
legge una pagina web
Arduino YUN va collegato via ETH a internet e con la seraiel a un pC
*/

#include <Bridge.h>
#include <HttpClient.h>

void setup() {
  SerialUSB.begin(9600);
  while (!SerialUSB); 
  
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  Bridge.begin();
  digitalWrite(13, HIGH);

  SerialUSB.println("pronti!");
}

void loop() {  
  HttpClient client;
  
  client.get("http://192.168.0.1/index.html#home");

  while (client.available()) {
    SerialUSB.println("Available");
    if  (client.find("tdCurrentFlux")) {
      SerialUSB.println("Trovato");
    String nextLine = client.readStringUntil('\n');
    SerialUSB.println(nextLine);
}
    //char c = client.read();
    //SerialUSB.print(c);
  }
  SerialUSB.flush();

  delay(5000);
}

C'è qualcosa che non torna... non è necessario accedere con user e password al router?
Mi sembra improbabile che un dispositivo del genere consenta di accedere senza, ed in tal caso come potrebbe il tuo sketch accedere ai dati senza prima fare il login?

Ciao, grazie per la risposta.
Si, per accedere al router va inserita una password.
Ho dato per scontato che una volta acceduti dal PC non chiedesse più la password hai nuovi accessi fino allo scadere del timeout automatico.
Si può con questa libreria inserire una variabile in un campo e poi dare l’invio?
Scusa la domanda stupida, ma non ho trovato informazioni a riguardo :grimacing:

Ovviamente questa cosa NON può accadere, più che una falla di sicurezza, sarebbe un enorme buco nero.

Per capire se è possibile e come fare il login con Arduino, prima di tutto è necessario capire come fa il login con il browser.
Se sei fortunato usa uno dei protocolli "standard" e quindi facilmente implementabili (perché noti) anche con Arduino.

Ad esempio questa è una richiesta ad un servizio che ho ora in prova su questo PC e che prevede uno schema di autenticazione detto "basic".

Se fosse cosi anche per il tuo router, quello che dovresti fare in questo caso è aggiungere l'header evidenziato con la stringa

    nome_utente:password

codificata in Base64 alla richiesta fatta con l'Arduino.

Hai perfettamente ragione.
Ho analizzato il codice sorgente della pagina di login del router, ma non ho trovato righe che fanno riferimento au una codifica. Ti allego lo screen relativo al campo per digitare la password.

Grazie per la tua pazienza.

No, non devi guardare il codice HTML, da li è difficile capire cosa accade.
Devi guardare gli headers della richiesta HTTP inviata dal browser nel momento in cui fai il login:

  • tab "network" dello strumento di sviluppo del browser;
  • fai un clear di quanto già eventualmente presente;
  • prova ad eseguire il login, magari con la password sbagliata cosi rimani nella stessa pagina;
  • ora seleziona la richiesta di login appena inviata con il browser ed analizza il tab "request headers" (oppure "Intestazioni delle richieste" se usi lo strumento di sviluppo in italiano).

Li dovresti trovare un header che indica il tipo di autorizzazione usata (più o meno come nell'immagine che ti ho allegato io nella risposta precedente).

Fatto, ho cercato negli Headers ma non ho trovato nessun riferimento al autenticazione. Lascio in allegato i file dei log e due screen.


Vedo il content type è un application/x-www-form-urlencoded ovvero come se stessi inviando dei dati con un form html con il metodo HTTP POST.

Prova a vedere nella tab "payload" sempre della richiesta; dovresti trovarci tutti i parametri che la pagina passa al router e magari la password è messa semplicemente li.

Ok, dovrebbe essere questo, giusto?



Effettivamente c'è scrivo password, ma non corrisponde a quella che inserisco nel campo perché è quella di default che è "admin".

La stringa "YWRtaW4=" corrisponde alla stringa "admin" codificata in base64.
Ci sono delle librerie anche per arduino se vuoi rendere la cosa dinamica, altrimenti puoi usare un tool online come ad esempio questo:

Adesso, viene il bello :wink:
Devi replicare la stessa richiesta che fa il browser con il tuo sketch su Arduino.

Imaginavo che arrivasse ora il bello :sweat_smile:
Io la stavo ragionando cosi:

  • Trovo ID del header corrispondente al campo del inserimento della password e inserisco la password in base64
  • Trovo ID del header del pulsante di conferma, così invio la password.

Cosa ne dici?

Che è del tutto inutile.

Non devi "replicare" il comportamento dell'utente con la pagina web servita dal router, ma quello che succede quando premi il pulsante di conferma. o in altre parole la richiesta HTTP che ti ho fatto analizzare fino ad ora alla pagina goform_set_cmd_process che viene richiesta in modo asincrono dalla pagina http://192.168.0.1/index.html (si evince alla presenza dell'header X-Requested-With: XMLHttpRequest)

In pratica la procedura di autenticazione dovrebbe essere qualcosa del genere:

  1. richiesta pagina "root" index.html
  2. invio dei dati di autenticazione con il metodo POST alla pagina http://192.168.0.1/goform_set_cmd_process
  3. elaborazione della risposta per fare il parsing delle informazioni che stai cercando

Puoi provare a vedere se riesci a fare l'autenticazione passando direttamente dal punto 2

Una richiesta POST di solito si fa tipo cosi:

String PostData = "someDataToPost";
if (client.connect(server, 80)) {
  // Invio degli headers
  client.println("POST /Api/AddParking/3 HTTP/1.1");
  client.println("Host: 192.168.0.1");
  client.println("User-Agent: Arduino/1.0");
  client.println("Connection: close");
  client.print("Content-Length: ");
  client.println(PostData.length());
  client.println();
  // Invio del payload
  client.println(PostData);
}

Nel tuo caso dovrai mettere gli headers che hai individuato con lo strumento di sviluppo (i più importanti, non sono necessari tutti: content-type, content-length eventualmente il referer etc etc) e poi il payload completo con tutti i campi.

isTest: false
goformId: LOGIN
password: et ctec

Se c'è tutto quello che è previsto e la password è giusta la successiva risposta del router sarà quella che ti aspetti ed a questo punto vai a cercare quello che ti serve.

Se vuoi fare dei test rapidi per cercare di capire esattamente quali sono le informazioni minime necessarie per il tuo router, ti consiglio di usare l'applicazione Postman con un PC in modo da costruire la richiesta HTTP pezzo per pezzo e valutare al volo la risposta del router.

Quando riesci a fare il login correttamente con Postman, trasferire tutto ad Arduino è un attimo

Grazie mille per la risposta molto esaustiva. Ho già installato Postman sul pc, comincio a fare le ultime prove che mi hai consigliato.
Una volta che ho testato la fattibilità dei comandi con postman, su arduino la libreria HTTPCLIENT è corretta per fare queste operazioni?

Se ha il supporto per il metodo POST, si certo.
Puoi anche "printare" direttamente la richiesta HTTP sull'oggetto client come nello spezzone di codice che ho messo più su.

Ah ok
Faccio un po di prove e vedo cosa succede.
Grazie ancora per le risposte :wink:

Domanda, ma se ineve di una pagina HTML dovessi fare la stessa cosa su una pagina JSON è possibile?
Intendo sempre eseguire il login e leggere delle variabili per poi utilizzare nello sketch.
Grazie

Certo che è possibile, cambia solo il tipo di pagina restituito dal server (JSON invece che HTML), ma il protocollo di comunicazione HTTP rimane lo stesso.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.