Estrazione codice da pagina web tramite vba

di il
16 risposte

Estrazione codice da pagina web tramite vba

Buongiorno.

Anni fa usavo il codice qui sotto per riportare in un file txt il codice di una pagina web, adesso però mi dà il seguente errore nella riga “Write…”:

                      Run-time error:   Method ‘Document’ of object ‘IWebBrowser2’ failed

Forse dipende dal fatto che “InternetExplorer” è obsoleto…. infatti ora che utilizzo il sistema Win10 penso sarebbe meglio, utilizzare (in vba) il browser Edge anzichè InternetExplorer… qualcuno potrebbe darmi un aiuto a risolvere il problema?

 Dim objIE As Object
 Set objIE = CreateObject("InternetExplorer.Application")
 objIE.Navigate "http://www.google.it/"   'esempio di sito web
 objIE.Visible = True
 Do While objIE.Busy    'oppure:  objIE.ReadyState <> 4
   DoEvents
 Loop
 
 Open "C:\MyPath\FileName.txt" For Output As #1
 Write #1, objIE.Document.body.outerHtml
 Close #1
 objIE.Quit
 Set objIE = Nothing

16 Risposte

  • Re: Estrazione codice da pagina web tramite vba

    05/12/2023 - Goemon ha scritto:


    utilizzare (in vba) il browser Edge anzichè InternetExplorer

    Non usi il controllo che fu web browser per IE ora sostituito dal controllo browser Edge? Se puoi usa quello.

    Altrimenti per un controllo completo del browser (Firefox, Edge, Chrome che sia) meglio usare Selenium.

  • Re: Estrazione codice da pagina web tramite vba

    Buongiorno.

    Phil purtroppo non ho mai usato il controllo web browser. Ho cercato su diverse pagine web, ma non ho trovato niente di esauriente.

    Con il seguente codice ho aperto una pagina web:

     Dim objEDGE As Object
    
     Set objEDGE = CreateObject("Shell.Application")
     objEDGE.ShellExecute "microsoft-edge:http://www.google.it/"
     
    
    

    ma non si può gestirla come con IE tramite un codice di questo tipo:

     Do While objEDGE.Busy    'oppure:  objEDGE.ReadyState <> 4
       DoEvents
     Loop
     
     Open "C:\MyPath\FileName.txt" For Output As #1
     Write #1, objEDGE.Document.body.outerHtml
     Close #1
     objEDGE.Quit
     Set objEDGE = Nothing

    perchè esce un Run-time error: "Object doesn't support this property or method"

    Ho trovato come ricavare il percorso del file MicrosoftEdge.exe, ma poi non so come gestire la pagina Edge

    Ho provato il codice:

     Dim obj4 As WebDriver
     Set obj4 = New ChromeDriver
     obj4.Start "Chrome"
     obj4.Get "http://www.google.it/" 

    oppure

     Dim obj4 As New WebDriver
     obj4.Start "Edge"
     obj4.Get "http://www.google.it/"

    ma mi esce: Compile error: User-defined type not defined

    Ho provato il codice:

     Dim obj4 As WebBrowserControl
     Set obj4 = CreateObject("Selenium.WebDriver")

    ma mi esce Run-time error: ActiveX component can't create object

    (Access365+Win10) 

    non saprei come procedere con e senza Selenium…

  • Re: Estrazione codice da pagina web tramite vba

    11/12/2023 - Goemon ha scritto:


    Phil purtroppo non ho mai usato il controllo web browser.

    Beh, niente di grave visto che bisogna scordarselo, ormai darebbe problemi su parecchie pagine web.

    Con i vari tentativi fatti che hanno dato sempre errori vari stai usando il sistema “alla Selenium”, ovviamente prima bisogna averlo installato.

    Qui di seguito metto il link alle pagine principali che trattano l'argomento, con i rispettivi software

    https://www.selenium.dev/ (comodo per l'IDE)

    https://github.com/GCuser99/SeleniumVBA

    https://florentbr.github.io/SeleniumBasic/

    https://stackoverflow.com/questions/76922904/selenium-vba-and-chromedriver-after-version-115

    11/12/2023 - Goemon ha scritto:

    Access365+Win10) 

    non saprei come procedere con e senza Selenium…

    Oh… ma allora metà dei problemi sono risolti: Access365 ha il nuovo controllo Edge Browser. Con quello fai (quasi) tutto. Se invece vuoi usare altri browser, per una scelta tua, Selenium è l'unica strada.

    Alcuni link di aiuto sull'uso del controllo Edge Browser:

    https://www.devhut.net/everything-you-never-wanted-to-know-about-the-access-modern-web-browser-control/

    https://support.microsoft.com/en-us/office/use-the-edge-browser-control-on-a-form-f9f731be-8f9b-4dd2-a5cb-525cfaed52d5

    (quest'ultimo rigorosamente in inglese, la versione in italiano a volte è affidabile, altre volte no, quindi prima in English e poi se ci sono problemi di comprensione passo all'italiano)

    Se vuoi vedere come gestire i reindirizzamenti per un caso concreto: https://www.utteraccess.com/topics/2065482

    (magari ce ne sono anche qui si iprogrammatori.it ma non li ricordo. Questo è fresco e quindi ancora in testa. Faccio mio quanto scrive il Phil_cattivocarattere su UtterAccess, mi ispira)

  • Re: Estrazione codice da pagina web tramite vba

    Grazie dei chiarimenti Phil.

    Dopo aver scaricato Selenium e selezionato in Access: Tools > References > "Selenium Type Library", ho provato il seguente codice:

    Dim strUrl As String
    Dim d As New EdgeDriver			'Dim d As New WebDriver
    
    strUrl = "http://www.google.it/"
    d.Get strUrl					'd.start "edge", strUrl
    d.Quit					

    ma mi esce:  Run-time error ‘21’: The driver failed to open the listening port 127.0…….. within 10s

    ho provato a trovare soluzioni al problema su internet ma non sono riuscito a risolverlo…

    qualcuno riesce ad aiutarmi?

  • Re: Estrazione codice da pagina web tramite vba

    Quando lo installai usai la Selenium Basic 2.0.9 ed ancora ho quella, per quelle 2 operazioncine che devo fare.

    La dichiarazione e l'assegnazione tienile sempre su righe separate, anche se troverai tanti esempi in cui  è scritto come hai fatto tu.

    Dim d As Selenium.EdgeDriver
    Set d = New Selenium.EdgeDriver

    poi… che dire… a me funziona. Ho letto in alcuni forum trovati cercando su internet che il file edgedriver.exe deve essere nel percorso

    C:\Users\<User Name>\AppData\Local\SeleniumBasic\

    Prima bisogna rinominarlo: se lo scarichi dal sito di Microsoft (https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/?form=MA13LH#downloads), nello zip trovi msedgedriver.exe, mentre nella cartella che ho scritto prima deve essere edgedriver.exe

    Il file deve essere compatibile con la versione di Ms Edge che hai. Se è aggiornato riscarica quella più recente.

    Se ancora non funziona dimmi cosa hai installato di Selenium (magari con il link, così non rischio di provare qualcosa di diverso) e riprovo con una situazione quanto più possibile simile alla tua.

  • Re: Estrazione codice da pagina web tramite vba

    Nel sito Selenium avevo cliccato su SeleniumBasic-2.0.9.0.exe, dando inizio alla procedura di installazione.
    Nella cartella:  "C:\Users\<User Name>\AppData\Local\SeleniumBasic\"  ci sono diversi file, tra i quali anche edgedriver.exe e chromedriver.exe.
    Il browser Edge con cui lavoro è aggiornato e la sua versione è: "Versione 120.0.2210.91 (Build ufficiale) (64 bit)".
    Ho provato il codice qui sotto che mi genera sempre il Run-time errore'21'.

     Dim strUrl As String 
     Dim d As Selenium.EdgeDriver        'Dim d As Selenium.ChromeDriver
     Set d = New Selenium.EdgeDriver     'Set d = New Selenium.ChromeDriver 
     strUrl = "https://www.google.it/"
     d.Get strUrl
     d.Quit

    Ho provato con il ChromeDriver e mi dà il seguente errore:
    Run-time error '13': UnknownError: cannot find Chrome binary
    (Driver info: chromedriver = 2.21.371459 
    (36d3d07f66..............), platform = WindowsNT 10.0 x86_64)

    Forse devo installare qualche altra versione di Selenium…? 

  • Re: Estrazione codice da pagina web tramite vba

    24/12/2023 - Goemon ha scritto:

    Il browser Edge con cui lavoro è aggiornato e la sua versione è: "Versione 120.0.2210.91 (Build ufficiale) (64 bit)".

    Forse devo installare qualche altra versione di Selenium…? 

    Se usi il webdriver che c'è nell'installazione di base di Selenium ricevi quell'errore: il file edgedriver.exe è a dir poco vecchiotto.

    Installa quello nuovo, scaricandolo dal link che ho indicato nel post precedente, e funziona, appena verificato. Non ho provato con Chrome, non lo uso.

  • Re: Estrazione codice da pagina web tramite vba

    Fino adesso avevo provato il codice al lavoro con A365+Win10, ora ho provato nel mio pc con A2010+Win11.

    In questo pc ho la stessa versione di Edge: Versione 120.0.2210.91 (Build ufficiale) (64 bit). 

    Sono entrato nel sito Microsoft Edge WebDriver suggerito da Phil, ho cliccato su X64 della Versione 120.0.2210.91 corrispondente a quella del mio browser Edge e dalla cartella “edgedriver_win64 (3).zip” ho scaricato il file "msedgedriver.exe" nella cartella "C:\Users\<User Name>\AppData\Local\SeleniumBasic\" creata appositamente.

    Ho rinominato il file "msedgedriver.exe" in "edgedriver.exe"

    Ho cliccato sul file “edgedriver.exe” e si è aperta la finestra nera qui sotto (stessa cosa se clicco sul file con nome "msedgedriver.exe")

    Nel file A2010 del mio pc non ho trovato la libreria: Strumenti > Riferimenti > "Selenium Type Library" e ovviamente il codice si blocca nell'assegnazione < Dim d As Selenium.EdgeDriver >

    Mi chiedo se devo fare prima l'installazione del vecchio file "SeleniumBasic-2.0.9.0.exe" che crea automaticamente la cartella SeleniumBasic e poi sostituire il vecchio file .exe con il nuovo file "edgedriver.exe" suggerito da Phill? 

  • Re: Estrazione codice da pagina web tramite vba

    24/12/2023 - Goemon ha scritto:

    Mi chiedo se devo fare prima l'installazione del vecchio file "SeleniumBasic-2.0.9.0.exe" che crea automaticamente la cartella SeleniumBasic e poi sostituire il vecchio file .exe con il nuovo file "edgedriver.exe" suggerito da Phill? 

    Eh sì.

  • Re: Estrazione codice da pagina web tramite vba

    Ho provato nel pc con Win11+A2010, ho installato il vecchio file "SeleniumBasic-2.0.9.0.exe" che crea automaticamente la cartella SeleniumBasic e poi sostituito il vecchio file .exe con il nuovo file "edgedriver.exe". A questo punto nel codice mi risultava “Errore di automazione” che ho risolto attivando la funzionalità di Windows ".NET Framework 3.5 ….." con le sue due sottovoci.

    Il seguente codice gira senza errori, ma la pagina web non si apre oppure appena si apre, si chiude immediatamente, nonostante abbia tolto il “d.Quit”.

     Dim strUrl As String 
     Dim d As Selenium.EdgeDriver       
     Set d = New Selenium.EdgeDriver    
     strUrl = "https://www.google.it/"     'sito indicativo
     d.Get strUrl

    Nell'altro pc di lavoro con Win10+A365 che è quello dove mi interessa usare il codice, la pagina web si blocca segnalando: “La tua connessione a questo sito non è sicura”.  Subito pensavo che fosse un blocco di sistema previsto dall'ADMIN, per il fatto che MS Edge è controllato da software di test automatizzato, come si legge in alto nella pagina web. Ma quando ho visto che esce questa stessa pagina di blocco anche nel pc con Win11+A2010 nel momento in cui si utilizza il codice:

     d.Get strUrl, 1    'o ,2 ,3 ,4, ...

    anzichè il codice:

    d.Get strUrl

    allora ho pensato che sia un problema risolvibile, ma non saprei come…?

  • Re: Estrazione codice da pagina web tramite vba

    27/12/2023 - Goemon ha scritto:

    Win11+A2010, …Il seguente codice gira senza errori, ma la pagina web non si apre oppure appena si apre, si chiude immediatamente, nonostante abbia tolto il “d.Quit”.

    (è uno strano concetto quello di “gira senza errori” se poi non fa quello che dovrebbe)

    Ho provato con Win10 e A2016 e A365 (due installazioni diverse, ho fatto il cambio nel frattempo), a me errori non ne dà. In questo istante però mi viene un dubbio. Dopo il Get hai eliminato il Quit, ok, ma c'è dell'altro o si esce dalla routine (Sub o Function che sia)? Perché è normale, in quel caso, che Edge si chiuda, l'oggetto webdriver esce dallo scope e viene automaticamente distrutto. Metti uno stop o un punto di interruzione (breakpoint).

    27/12/2023 - Goemon ha scritto:

    Nell'altro pc di lavoro con Win10+A365 che è quello dove mi interessa usare il codice, la pagina web si blocca segnalando: “La tua connessione a questo sito non è sicura”.

    Torno a sottolineare che se hai A365 puoi sfruttare il controllo Edge Browser, direttamente dentro una maschera.

    Anch'io se metto il timeout con il metodo Get ho lo stesso errore ma perché metterlo se non serve, visto che senza almeno per me funziona? Ovviamente ho provato con la pagina principale di google, magari tu hai usato un sito particolare che ha comportamenti diversi. In questo caso o dici qual è, se è possibile, oppure è impossibile replicare il problema.

  • Re: Estrazione codice da pagina web tramite vba

    Quando un codice “gira senza errori” ma non fa quello che dovrebbe, potrebbero esserci dei problemi non derivanti dal codice, ma da altri fattori come per esempio le impostazioni del sistema operativo. Forse questo è il motivo per cui facendo girare lo stesso codice su Win10+A365, nel mio pc la pagina web va in loop bloccandosi come pagina “non sicura”, mentre nel pc di Phil la pagina si apre senza problemi (sempre intendendo la pagina principale di Google).

    Su Win11+A2010 la pagina si chiude subito perchè dopo il Get c’è “End Sub”, ma inizialmente pensavo che la pagina Edge rimanesse aperta come quando si usava l’Internet Explorer, anche dopo “Quit”, “End Sub”. Quale potrebbe essere un comando di interruzione, che tiene aperta la pagina Edge anche dopo che si è chiuso il file Access?

    L’estrazione di codice da pagina web, vorrei utilizzarla (come spesso accade) per poi eseguire tramite vba, il login di accesso ad alcune pagine web di lavoro. Prima di affrontare il metodo del “Controllo Edge Browser”, volevo capire se tale metodo oltre a riportare in una maschera il codice di una pagina web, può essere utilizzato anche per eseguire il login (inserendo dati e premendo pulsanti nella pagina web).... ?

  • Re: Estrazione codice da pagina web tramite vba

    Usa sempre lo stesso codice, in entrambi gli ambienti, altrimenti non si capisce più cosa può essere dovuto alla particolare configurazione o altro.

    Riepilogo:

    1. Non usare il .Get con il parametro di logout, tieni il classico .Get strUrl
    2. Se subito dopo il .Get c'è un Exit Sub è più che normale che il browser controllato da Selenium si chiuda. Potrebbe essere talmente veloce che ti sembra che non si apra nemmeno.

    30/12/2023 - Goemon ha scritto:

    inizialmente pensavo che la pagina Edge … anche dopo “Quit”.

    Questo è impossibile altrimenti il .Quit che senso avrebbe? Se vuoi tenerlo aperto non devi usare .Quit.

    30/12/2023 - Goemon ha scritto:

    Quale potrebbe essere un comando di interruzione, che tiene aperta la pagina Edge anche dopo che si è chiuso il file Access?

    Impossibile 2, la vendetta. Dopo ti spiego come tenere aperto Edge, sempre sotto il controllo di Selenium, ma con il file accdb ancora aperto. Nel momento in cui chiudi il file accdb (o accde che sia), tutto quello che era gestito tramite codice inevitabilmente deve terminare. A meno che tu non abbia lanciato altro di cui però non avevi il controllo, a titolo d'esempio un FollowHyperLink di un documento di Word: anche se chiudi Access il documento di Word rimane aperto perché con il FollowHyperLink hai semplicemente aperto il file con il programma predefinito, non hai avviato Word come server di automazione. Aggiungo poi una considerazione: alla base di tutto c'è la necessità di controllare il browser (Edge, nello specifico) tramite codice, senza intervenire manualmente. Se chiudi “il codice”, significa che hai finito di controllare il browser. Se ti serve un'istanza normale puoi lanciarla come ultima azione, come si aprirebbe un programma qualsiasi.

    Quello che puoi fare è sicuramente aprire il browser (gestito con Selenium) all'interno di una routine e mantenerlo “in vita” anche quando esci dalla routine (l'End Sub per restare nell'esempio). Devi fare in modo che la variabile abbia uno scope più ampio della singola routine. Qui dipende da quanto vuoi che resti “in vita”: se a livello di oggetto (ad esempio finché una determinata maschera è aperta) o se a livello di intera durata del programma (file accd* aperto).

    A livello di oggetto (maschera): dichiari la variabile all'inizio del modulo, fuori da ogni routine, con il modificatore Private (andrebbe bene anche Dim ma Private è più adatto, rende meglio l'idea)

    Option Explicit
    Option Compare Database
    
    Private d As Selenium.EdgeDriver
    
    Private Sub ApriEdge
      Dim strUrl As String 
      Set d = New Selenium.EdgeDriver    
      strUrl = "https://www.google.it/"     'sito indicativo
      d.Get strUrl
    End Sub

    Come detto prima non devi mettere il .Quit altrimenti chiedi di fare l'esatto contrario di quello che vorresti. Anche se si esce dalla routine la variabile “d” non è uscita dallo scope e quindi non viene distrutta perché dichiarata a livello di modulo dell'oggetto: finché quell'oggetto rimane aperto (continuo a pensare alla classica maschera) Edge restera a perto e controllato da Selenium. Potresti avere un'altra routine di questo tipo

    Private Sub CambiaPagina
      Dim strUrl As String 
      strUrl = "https://www.bing.com/"     'sito indicativo
      d.Get strUrl
    End Sub

    e fai fare all'oggetto associato a d quello che vuoi, perché è sempre lo stesso Edge di prima controllato da Selenium.

    Se vuoi invece che il Edge rimanga aperto fino a quando non chiudi il file accd*, dichiari la variabile a livello di modulo generale con un 

    Global d As Selenium.EdgeDriver

    In qualunque punto del codice puoi istanziare d (una volta sola, ovviamente) e gestirlo. Solo quando chiudi il file accd* d viene distrutto, anche se è bene esplicitare un d.Quit ed un Set d = Nothing.

    Se non vuoi usare un modulo generale ma una variabile globale dichiarata in un modulo oggetto potresti usare una maschera che apri all'avvio del file accd* ma che rimane sempre nascosta. Quando chiudi il file anche quella maschera sarà chiusa e nell'evento Close chiudi Edge e distruggi la variabile.

    30/12/2023 - Goemon ha scritto:

    utilizzato anche per eseguire il login (inserendo dati e premendo pulsanti nella pagina web).... ?

    Con Selenium puoi fare anche questo. Lì però sarà difficile per me aiutarti perché dipende dalla pagina specifica. Sicuro di voler automatizzare anche l'autenticazione? Intendi inserire i classici nome utente e pwd? Stai attento al discorso sicurezza, e qui si apre un altro mondo.

    Note conclusive: 

    Forse c'è qualche eccezione a quello che ho scritto in merito ad apertura e “ripresa” del controllo dei programmi tra due distinte aperture di Access ma credo serva una conoscenza tosta delle API, che io non ho.

    Dovesse esserci bisogno di più variabili dello stesso tipo, evita di dar loro lo stesso nome solo per il fatto che hanno scope diversi. E' una grana poi capire quale variabile si sta usando (c'è una priorità nella scelta della variabile da usare in caso di “omonimia” ma con scope diversi). Siccome non cosa nulla, usa nomi diversi.

  • Re: Estrazione codice da pagina web tramite vba

    Grazie a Phil degli approfondimenti. 

    L’obiettivo era quello di aprire una pagina web di login (di un software che si trova su cloud) utilizzando il browser predefinito Edge, poi eseguire l’autenticazione e poi utilizzare il software. A questo punto, l'applicativo si può anche chiudere perchè non serve più.

    (al posto di un applicativo .accdb, eventualmente potrei usare un file .vbs). 

    L’autenticazione è a due fattori e quindi divisa in due fasi.

    Problemi con IE (Internet Explorer)

    Ho riprovato il codice del mio primo post (con objIE) e stranamente ora il problema è svanito e il codice funziona.

    Però provando manualmente con IE, si riesce a fare l’autenticazione, ma poi si blocca la pagina perché il software deve girare solo su Edge.

    Problemi con EdgeDriver di Selenium

    Con l'EdgeDriver, nell’ambiente Win10+A365, non riesco aprire la 1° pagina di login perchè si blocca. Inoltre il browser Edge si chiude con la chiusura dell’applicativo a differenza di IE che rimane aperto anche dopo “End Sub” e dopo la chiusura dell’applicativo.

    _______________________________________________________________________________________________

    Rimanendo sull’argomento della discussione, in questi giorni ho trovato un metodo carino per estrarre codice da pagina web, senza utilizzare Selenium o il “Controllo Web Browser”.  Lo chiamo metodo HTTP e posto una routine di esempio che estrare il codice in un file .txt:

     Dim strUrl As String
     Dim strPath As String
     Dim objHTTP As Object
     
     strUrl = "https://www.google.it/"
     strPath = "C:\MyPath\FileName.txt"
     
     Set objHTTP = CreateObject("MSXML2.XMLHTTP")
     objHTTP.Open "GET", strUrl, False
     objHTTP.send
     Open strPath For Output As #1
     Write #1, objHTTP.responseText
     Close #1
     
     Set objHTTP = Nothing
    
Devi accedere o registrarti per scrivere nel forum
16 risposte