Guida al Visual Basic .NET
Capitolo 80° - Parsing di codice HTML
È possibile scaricare pagine web in molti modi diversi, di cui WebBrowser è solo il primo che ho introdotto. Nel capitolo
precedente non ci siamo posti alcun problema sull'analsi del codice di una pagina, poiché l'importante era riuscire a visualizzarla
ed a navigare da essa ad alre pagine presenti in rete. Tuttavia, presto o tardi incorrerete nel bisogno di ottenere informazioni sui tag
html presenti in un data pagina, ad esempio per effettuare un login automatico senza essere personalmente al computer, o per aggiungere
alcune funzionalità al browser che state scrivendo di nascosto. Uno sguardo alle classi
HtmlDocument è la classe di partenza, che ci permette di iniziare ad ispezionare il codice. Essa non espone costruttori, né metodi statici, e quindi non esiste alcun modo di inizializzarla o di applicarla ad un file html. L'unico modo in cui possiamo ottenerne un'istanza è attraverso la proprietà Document del controllo WebBrowser. HtmlDocument espone alcuni membri interessanti:
Gli oggetti HtmlElement contengono più o meno gli stessi membri, con l'aggiunta di GetAttribute e SetAttribute per modificare
gli attributi di un tag. Login automatico
Ecco un modo con cui potreste automatizzare il login in una pagina salvando le informazioni e compilando i campi con un solo pulsante. Class Form1 'Qui c'è il codice del capitolo precedente 'Ecco il dizionario che contiene tutto Dim LoginInfo As New Dictionary(Of String, Dictionary(Of String, String)) Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'Per semplicità, in questo esempio carichiamo dei 'dati di prova al caricamento del form Dim TInfo As New Dictionary(Of String, String) With TInfo 'ID del form di login .Add("form-id", "totemlogin") 'ID della textbox per l'username .Add("username-field", "lname") 'ID della textbox per la password .Add("password-field", "lpassw") 'Username e password .Add("username", "prova") .Add("password", "prova") End With 'Associa alla pagina il suo login LoginInfo.Add("http://totem.altervista.org/guida/versione3/login.php", TInfo) End Sub Private Sub btnAction_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAction.Click 'Quando viene premuto il pulsante, ricava il dizionario 'dei dati dall'url della pagina Dim Info As Dictionary(Of String, String) = LoginInfo(wbBrowser.Url.ToString()) 'Quindi compila i campi e invia la richiesta di login With wbBrowser.Document .GetElementById(Info("username-field")).SetAttribute("value", Info("username")) .GetElementById(Info("password-field")).SetAttribute("value", Info("password")) 'InvokeMember invoca un metodo usabile da un 'certo elemento. I metodi sono gli stessi che si 'usano in javascript .GetElementById(Info("form-id")).InvokeMember("submit") End With End Sub End Class
Nonostante possa semprare inutile, questo approccio potrebbe diventare molto più intrigante, ad esempio, se l'utente immettesse semplicemente
una tessera o una chiavetta in un dispositivo collegato al computer e, usando il vostro browser, potesse interfacciarsi con tale
dispositivo per automatizzare e personalizzare tutti i login a seconda dell'utente. Oppure potreste sfruttare il riconoscimento vocale
offerto dalle librerie del framework 3.5 per confermare l'accesso mediante una parola detta a voce. Trasformazioni
Nel paragrafo precedente ho mostrato come modificare degli elementi. In questo mostrerò come aggiungere nuovi elementi alla pagina
dinamicamente e come gestirne gli eventi. Class Form1 '... Private Sub btnAction_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAction.Click With wbBrowser.Document 'Scorre tutte le immagini nella pagina e ad ognuna 'aggiunge un nuovo gestore d'evento per l'evento OnClick. 'Il metodo AttachEventHandler può essere usato 'da qualsiasi HtmlElement, ed accetta come primo 'parametro il nome dell'evento da gestire (vedere la 'documentazione ufficiale W3C) e come secondo un 'delegate che punta al sottoscrittore. For Each img As HtmlElement In .Images .AttachEventHandler("onclick", AddressOf ImageToLink) Next End With End Sub 'Questo è il nuovo gestore d'evento. Nonostante i 'parametri, sender è sempre Nothing Private Sub ImageToLink(ByVal sender As Object, ByVal e As EventArgs) 'Ottiene un riferimento all'immagine con il metodo 'GetElementFromPoint, sfruttando il fatto che questo 'codice viene eseguito subito dopo un click. 'MousePosition indica la posizione del mouse sullo schermo, 'Me.Location determina la posizione del form sullo schermo 'e wbBrowser.Location la posizione del browser sul form. 'La differenza tra questi punti è la posizione 'del mouse rispetto al browser. Anche se un po' grezzo, 'questo metodo dovrebbe funzionare abbastanza Dim Img As HtmlElement = wbBrowser.Document.GetElementFromPoint(MousePosition - Me.Location - wbBrowser.Location) 'Crea un nuovo link mediante il metodo CreateElement 'di HtmlDocument Dim Link As HtmlElement = wbBrowser.Document.CreateElement("a") 'Imposta l'attributo href dell'immagine Link.SetAttribute("href", Img.GetAttribute("src")) 'Imposta il testo del link If Not String.IsNullOrEmpty(Img.GetAttribute("longdesc")) Then Link.InnerText = Img.GetAttribute("longdesc") ElseIf Not String.IsNullOrEmpty(Img.GetAttribute("alt")) Then Link.InnerText = Img.GetAttribute("alt") Else Link.InnerText = "Immagine" End If 'Aggiunge il link prima dell'immagine Img.INSERT IGNOREAdjacentElement(HtmlElementINSERT IGNOREionOrientation.BeforeBegin, Link) 'Dato che non è possibile eliminare elementi, 'impone all'immagine larghezza 0 Img.SetAttribute("width", "0") End Sub End Class
C#, TypeScript, java, php, EcmaScript (JavaScript), Spring, Hibernate, React, SASS/LESS, jade, python, scikit, node.js, redux, postgres, keras, kubernetes, docker, hexo, etc...
|