Estrarre un elemento da pagina Web con WebView2 e Javascript

di il
17 risposte

Estrarre un elemento da pagina Web con WebView2 e Javascript

Buongiorno, volevo chiedere un suggerimento su come leggere il testo di un elemento HTML da una pagina web utilizzando Javascript in associazione a WebView2..

In particolare vorrei leggere una pagina Yahoo Finance ed estrarre il prezzo di un titolo. Analizzando la pagina con firefox ho visto che il dato è presente in un elemento con id “quote-header-info”. Provo a leggere il suo testo, dopo avere atteso che la pagina sia stata completamente caricata dal browser Vb.net, con la semplice sub qui sotto:

   Private Async Sub Wv2_NavigationCompleted(sender As Object, e As CoreWebView2NavigationCompletedEventArgs) Handles Wv2.NavigationCompleted
      
       'già caricata la pagina yahoo con simbolo qualsiasi, esempio McDonalds : https://finance.yahoo.com/quote/MCD/

       Dim dato_estratto As String
       Dim stringa_query As String

       'preparo una stringa di selezione Javascript 
       stringa_query = "document.querySelector('#quote-header-info').innerText;"

       'provo a leggere il risultato 
       dato_estratto = Await Wv2.ExecuteScriptAsync(stringa_query)
       
       'assegno ad un textboxt il testo letto
       Txt_testo_sito.Text = estrai_dato(dato_estratto)

   End Sub


   ottengo sempre "null" come risultato, anche se uso queste altre stringhe di selezione che indico di seguito:
   
   stringa_query = "document.querySelector('#quote-header-info').innerHTML;"
   stringa_query = "document.querySelector('#quote-header-info').outerHTML;"
   stringa_query = "document.querySelector('fin-streamer').textcontent;" 

Avete qualche suggerimento sulla costruzione della corretta query Javascript per ottenere il prezzo del titolo?

Ringrazio in anticipo e saluto!

17 Risposte

  • Re: Estrarre un elemento da pagina Web con WebView2 e Javascript

    Ho aperto Firefox sul link che hai indicato
    Click destro, ho selezionato “analizza”
    Sono andato sulla sezione “console”
    Ho digitato:
    document.querySelector('#quote-header-info').innerText;
    ho dato “invio” e mi ha dato errore dicendo:
    Uncaught TypeError: document.querySelector(...) is null

    E' chiaro quindi che il problema non è su WebView2 o su codici di programma, ma che non riesci a selezionare l'elemento che ti serve

    P.S.: io non sono riuscito a trovare l'elemento quote-header-info nel codice HTML

    Secondo me dovresti cercare il tag <fin-streamer> con classe “livePrice” e poi ricavarti da questo l'attributo data-value,
    ad esempio: 

    document.querySelector('fin-streamer.livePrice').getAttribute('data-value');
  • Re: Estrarre un elemento da pagina Web con WebView2 e Javascript

  • Re: Estrarre un elemento da pagina Web con WebView2 e Javascript

    Grazie per la risposta, SirJo..

    Nell'immagine sopra ti mostro il testo che vorrei estrarre, che corrisponde al valore scritto con i grossi font neri al valore di 306.33..

    Come vedi nell'ispector della pagina di Firefox, si trova sotto l'elemento con Tag fin-streamer etc.., quello rappresentato in basso nell'immagine.. Non sapendo come creare la query JS per questo elemento super-annidato  (ho provato con la copia dei CSS selector di Firefox ma non funziona lo stesso), allora sono risalito fino al primo elemento che lo contenesse ("quote-header-info" visibile nell'immagine sopra), e che avesse un ID relativamente semplice da selezionare con JS. Ma niente da fare, rende sempre “null”). 

    Esiste un buon libro con tanti esempi per usare questo WebView2 con JS?  oppure un sito informativo davvero ben spiegato? 

    E' una colossale perdita di tempo cercare gli elementi del DOM in questo modo. Rimpiango moltissimo il classico webbrowser, ma non voglio sviluppare una nuova applicazione con un controllo che non è più suggerito..

    Grazie 

    PS: anche io non trovo ('fin-streamer.livePrice') che hai menzionato, ma è certamente dovuto alla mia inesperienza.. Come lo cerco?

    Ho messo in console.log la tua stringa, ma da null anche quella..

  • Re: Estrarre un elemento da pagina Web con WebView2 e Javascript

    Ciao SirJo,

    Ho provato ad inserire la tua stringa nel codice VB, e funziona, estrae correttamente il valore richiesto!

    Utilizzando la console di Firefox non ottenevo invece il dato.. Anche di questo strumento devo approfondire conoscenza per riuscire ad utilizzarlo, in quanto sono sicuro che sbaglio qualcosa io quando scrivo:

    let dato= document.querySelector('fin-streamer.livePrice');

    console.log  (dato).getAttribute('data-value');

    Mi dà un errore alla seconda riga che dice “undefined”.

    Grazie per quanto sopra. Ora devo imparare a trovare nelle pagine web in generale gli elementi voluti e generare il corretto codice Javascript da inserire in VB utilizzando WebView2; vorrei poter utilizzare questo metodo per prendere qua e là qualche info sulle pagine web di tanto in tanto nei miei programmi.

    Sto cercando materiale di studio in merito, ma non sono ancora riuscito a trovare cose scritte in modo esaustivo e semplice, con esercizi inclusi. Ogni suggerimento è benvenuto.

    Buona serata!

  • Re: Estrarre un elemento da pagina Web con WebView2 e Javascript

    Mi sono accorto che a volte il valore nell'attributo data-value non corrisponde esattamente al valore visualizzato, per cui meglio se usi

    document.querySelector('fin-streamer.livePrice').innerText;


    la riga che va in errore deve essere

    console.log(dato.getAttribute('data-value'));


    comunque, se in Firefox apri la sezione “console”, basta che digiti 
    document.querySelector('fin-streamer.livePrice').innerText;
    e dai invio, non serve fare altro, vedi il risultato senza dover usare console.log

  • Re: Estrarre un elemento da pagina Web con WebView2 e Javascript

    Grazie SirJo,

    anche la seconda stringa che proponi va bene.. Ma come potevo arrivare a trovare il giusto elemento con il suo tag name?

    Ho copiato da Firefox tutto il contenuto pagina HTML in un editor esterno e cercato ovunque il testo “fin-streamer.livePrice” senza trovarlo.. Grazie per una tua dritta anche per identificare gli elementi.. Io usavo analisi pagina di Firefox, puntando il cursore su ciò che interessava e poi con il tasto destro facendo “copia Css selector”, ma non funziona quando lo uso per  Javascript.

    Anche visualmente leggendo la struttura HTML dell'elemento e provando a selezionarlo (come nel caso di " document.querySelector('#quote-header-info').innerText;" Ottengo errori o ritorno null. Sicuramente sbaglio qualcosa.

    Anche il tuo ultimo suggerimento dà null in Firefox (vedi immagine seguente), forse tu ne usi una versione diversa (credo esista una per sviluppatori)?

    27/09/2024 - SirJo ha scritto:


    comunque, se in Firefox apri la sezione “console”, basta che digiti 
    document.querySelector('fin-streamer.livePrice').innerText;
    e dai invio, non serve fare altro, vedi il risultato senza dover usare console.lo

  • Re: Estrarre un elemento da pagina Web con WebView2 e Javascript

    Utilizzo Firefox normale


  • Re: Estrarre un elemento da pagina Web con WebView2 e Javascript

    Ma come potevo arrivare a trovare il giusto elemento con il suo tag name?

    Per trovare il giusto elemento ci vuole un po' d'occhio, un po' di esperienza, e conoscenza dell'HTML

    Dall'immagine che ti allego, ho visto che l'elemento padre aveva una classe “livePrice”, e questo mi ha fatto capire che è il prezzo attuale.
    Ho cercato nel codice HTML la parola “livePrice” ed ho visto che è presente solo in quel elemento.

    e cercato ovunque il testo “fin-streamer.livePrice” senza trovarlo


    Non trovi la scritta fin-streamer.livePrice perchè non c'è, ma nel parametro querySelector significa “un oggetto con tag fin-streamer e classe livePrice”, che è proprio quello che stiamo cercando

  • Re: Estrarre un elemento da pagina Web con WebView2 e Javascript

    Grazie SirJo,

    credo di aver trovato il problema: Io continuavo ad usare il “vecchio” sito di Yahoo Finance… avevo inizialmente fatto delle prove su di una pagina che avevo salvato per farvi accesso da hard-disk off-line e non da web durante le mie prove.. 

    Poi comunque Yahoo continuava a ricaricarmi le pagine (solo visualmente, ma non quando interrogavo il sito con Webviev2 e Javascript, che riportavano l'HTML del NUOVO sito) con il vecchio formato, che risultava quello che vedi nelle mie immagini sopra. Ovviamente il suo HTML era leggermente diverso, per cui non vi era lo stesso elemento a cui mi hai indirizzato tu! 

    Quindi analizzavo una pagina diversa da quella ottenibile con la query JS..

    Grazie per i tuoi preziosi suggerimenti, cercherò materiale per approfondire e fare esercizi con le query JS.

    Buon weekend!

    PS: ti metto qui uno snapshot del sito che vedevo io.. bisognava cliccare sul “prova il nuovo sito” e poi i cookies avrebbero definitivamente indirizzato il mio Firefox, negli accessi futuri, alla stessa pagina che vedevi tu..

  • Re: Estrarre un elemento da pagina Web con WebView2 e Javascript

    Ottimo !!!

    Domanda: ma tu hai bisogno di mostrare il sito all'utente ??
    O devi semplicemente ricavarti quei valori dalla pagina HTML ??

    Perchè se hai solo bisogno di ricavarti il valore cercato, puoi evitare di usare WebView2, dato che non hai bisogno di fare login o cose strane, e non credo ti servano nemmeno le pubblicità e le immagini che appaiono, compreso grafico eccetera.
    Puoi quindi utilizzare un oggetto WebClient, scaricarti la pagina HTML ed estrarti il dato cercato con una banale RegularExpression 

    Se hai bisogno chiedi pure

  • Re: Estrarre un elemento da pagina Web con WebView2 e Javascript

    No, non devo mostrare nulla..

    avevo già un'applicazione che scaricava la tabella prezzi dalla pagina dati storici e poi il singolo prezzo attuale (che nella tabella non era presente). Usavo questa tecnica:

     stringa_query = "https://query1.finance.yahoo.com/v7/finance/download/"

     Dim richiesta As Net.HttpWebRequest = Net.HttpWebRequest.Create(stringa_query)

    Poi lavoravo sulla webresponse etc..

    Ma da un pò di tempo Yahoo blocca le query e richiede di essere loggati.. Così ho pensato di tirare fuori dal DOM della pagina le cose che m'interessavano con un pò di webscraping. Microsoft aveva obsoletato da tempo il vecchio webbrowser basato sul motore di Explorer, e dovevo imparare ad usare qualcosa di attuale, per non rischiare di mettere mano al codice dopo poco tempo per obsolescenza.. 

    Ho visto che anche Webrequest ed HTTPWebrequest li avevano anch'essi obsoletati, e mi sono deciso a battere un pò la testa sul controllo da loro suggerito per nuove applicazioni: Webview2. Poi questo si è portato appresso anche Javascript, e quindi ho iniziato a fare test con questi strumenti. 

    Quando faccio qualcosa di nuovo cerco poi di apprendere i principi generali, non solo di risolvere il singolo problema (in questo caso serviva solo estrarre il solo prezzo attuale), così da poter usare le nozioni acquisite anche per future necessità.

    All'accoppiata Webclient/Regex non avevo pensato, se dici che non richiede troppo tempo per essere imparata, provo a valutare anche questa.. Però come vedi bisogna andare sulla nuova classe HttpClient, perchè MSFT ha obsoletato anche WebClient.

    Suggerisci qualcosa usando HTTPClient? Ma poi questo tornerebbe a fare richieste HTTP che il server di Yahoo rifiuta se non sei loggato e/o hai una username/password?

  • Re: Estrarre un elemento da pagina Web con WebView2 e Javascript


    Io sono riuscito a scaricare senza problemi la pagina di yahoo, non serve login

            Dim url As String = "https://finance.yahoo.com/quote/MCD/"
            Dim client = New HttpClient
            client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0")
            Dim result As String = client.GetStringAsync(url).Result


    io nei miei programmi continuo ad usare WebClient, sarà anche obsoleto ma funziona perfettamente

    …. hai bisogno anche di un aiuto con le RegEx ??

  • Re: Estrarre un elemento da pagina Web con WebView2 e Javascript

    Nella mia query che in precedenza funzionava senza necessità di login, scaricavo la tabella dati storici con la programmazione, invece che farlo manualmente con il bottone che c'era sulla pagina Yahoo “download”..

    Ora non consentono più di scaricare i dati in formato csv senza essere registrati etc.. Nel nuovo sito, quello che hai visto anche tu, non c'è più la possibilità per qualsiasi utente di scaricare la tabella in csv cliccando un bottone o con una query d'importazione in Excel diretta.

    Proverò anche il metodo che proponi, penso funzioni per la pagina “base” e per estrarre il singolo prezzo, ma debbo provare anche ad estrarre un pò dei dati contenuti nella tabella storica. Pensavo che meglio che lavorare sulle stringhe di testo su tutta la pagina estratta, sarebbe stato il caso d'imparare a fare l'estrazione dei singoli elementi dal DOM (inclusa tabella storica);

    Visto che farlo con il vecchio webbrowser (anche questo, tra l'altro, è obsoleto ma si può ancora utilizzare) era semplice, ho voluto provare ad apprendere la nuova soluzione che MSFT propone, Webview2. Molto più potente (mi sembra), ma decisamente complesso da imparare e richiede anche conoscenza di Javascript.

    Grazie per la tua disponibilità, sicuramente chiederò ancora una mano prossimamente, dopo avere fatto un pò di prove.

    Buona Domenica!

  • Re: Estrarre un elemento da pagina Web con WebView2 e Javascript


    Su alcuni programmi che ho utilizzo ancora il buon vecchio WebBrowser, ma solo perchè devo navigare su siti che sono compatibili con Internet Explorer 11.
    Quando ho dovuto passare ad livello superiore ho provato WebView2 ma ho trovato molta difficoltà perchè, come hai già capito tu, l'esplorazione del DOM è praticamente impossibile se non tramite JS.
    Sono quindi passato all'uso di Selenium, una libreria gratuita con cui mi trovo molto bene, ma che non è un oggetto che metti nel form (come invece WebBrowser e WebView2), viene proprio lanciato Google Chrome (oppure Firefox, Edge, come preferisci tu) e poi utilizzi dei comandi potenti per analizzare il DOM, per simulare il click sugli elementi, per simulare l'inserimento di dati da tastiera, oppure il click del mouse in un determinato punto, eccetera.

    Se vuoi inglobarlo su di un form, io ho fatto una procedura che, una volta che si carica Google Chrome, lo posiziono dentro un panel che ho nel form (tramite il .parent).

    Se non vuoi vedere che si carica Google Chrome puoi comunque configurarlo in modalità headless, e l'utente non vede nulla

Devi accedere o registrarti per scrivere nel forum
17 risposte