Sviluppare funzionalita su Microsoft Office con VBA Importare dati in tabella excel da una pagina web

Login Registrati
Stai vedendo 13 articoli - dal 26 a 38 (di 38 totali)
  • Autore
    Articoli
  • #10981 Score: 0 | Risposta

    Salve, in questi giorni ho avuto un po di tempo per riprendere sottomano questo codice e rifilarlo per applicarlo appieno all'applicazione che voglio realizzare.

    Ho subito aggiustato questo:

    For Each tdtd In trtr.Cells
        Cells(i + 1, j + 1) = tdtd.innertext
        j = j + 1
    Next tdtd
    

    in questo:

    For Each tdtd In trtr.Cells
        Cells(i + 1, j + 1) = Trim(tdtd.innertext)
        j = j + 1
    Next tdtd
    

    così da rimuovere eventuali spazi posti prima e dopo la stringa estratta.

    Poi ho diviso la Sub in tante Sub, ognuna che estragga un singolo elemento ad esempio SUB REGIA(), dove sto perfezionando opportunamente l'estrazione del regista, pulendolo da spazi e colonne che non mi interessano; idem per CAST, Musiche, Ecc.

    Mi sono però imbattuto in un problema nell'estrazione di Produzione e Distribuzione che si trovano ad un'altra pagina e non sembrano strutturate in TABLE come nella precedente.

    Questo il link: https://www.imdb.com/title/tt0227445/companycredits

    La struttura sembrerebbe suddivisa in modo diverso da gruppi "tr" e "td" ma in gruppi "li" che non so gestire perché non conosco il codice html. Di seguito quello che ho provato a fare ma sono tentativi a vuoto senza realmente capire ciò che sto facendo:

    Sub Produzione()
        'dichiarazione delle variabili e loro tipizzazione
        Dim IE As Object                        ' un oggetto web browser che punta a un sito
        Dim i As Long, j As Long, kk As Long    ' variabili contatori di supporto
        Dim myColl As Variant                   ' contiene il contenuto della pagina internet
        Dim myItm As Variant                    ' ogni elemento di sezione dentro la pagina internet
        Dim myURL As String                     ' indirizzo internet da raggiungere
        Dim trtr As Variant, tdtd As Variant    ' riferimenti alle righe delle tabelle della pagina internet
        Dim sections As Variant                 ' qui sono contenuti i titoli delle diverse sezioni,
                                                ' che poi saranno filtrati dalla costante iniziale
        Const TITLES As String = "Production"     'la costante TITLES serve da filtro per le sezioni da recuperare
        
        'imposta internet l'indirizzo da raggiungere
        myURL = "https://www.imdb.com/title/tt0227445/companycredits"
        'crea l'oggetto internet explorer
        Set IE = CreateObject("InternetExplorer.Application")
    
        'legge il contenuto della pagina internet
        'e lo assegna alla variabile IE
        '(metodo classico)
        With IE
            .Navigate myURL
            .Visible = True
            Do While .Busy: DoEvents: Loop 'Attesa not busy
            Do While .ReadyState <> 4: DoEvents: Loop 'Attesa documento
        End With
        
        'imposta un riferimento all'insieme degli elementi con tag H4 della pagina internet
        Set sections = IE.Document.getElementsbyTagName("H4")
    
        'si posiziona sul foglio Excel desiderato per riversarvi i dati
        'e cancella la zona usata in precedenza
        Application.Goto Sheets("Importa_Produzione").Range("A1")
        ActiveSheet.UsedRange.Clear
        
        'imposta un riferimento all'insieme degli elementi della sezione TABLE del documento
        'e scorre ogni elemento per recuperarne il contenuto desiderato
        'se il testo della sezione è contenuto nella costante TITLES
        'di ogni elemento, poichè è memorizzata come tabella,
        'scorre riga per riga e ne ricava il testo, che inserisce nel foglio Excel
        'in una riga dedicata, indentando a partire dalla colonna A in avanti
        i = 0
        kk = 0
        Set myColl = IE.Document.getElementsbyTagName("UL")
        For Each myItm In myColl
            If contains(TITLES, sections(kk).innertext, ",") Then
                i = i + 1
                Cells(i, "A").Value = sections(kk).innertext
                For Each trtr In myItm.Rows
                    For Each tdtd In trtr.Cells
                        Cells(i + 1, j + 1) = Trim(tdtd.innertext)
                        j = j + 1
                    Next tdtd
                    i = i + 1: j = 0
                Next trtr
                i = i + 2
            End If
            kk = kk + 1
        Next myItm
        
        'operazioni finali
        Range("A1").Select
        ActiveSheet.UsedRange.WrapText = False
        
        'esce dall'applicazione internet e distrugge l'oggetto in memoria
        IE.Quit
        Set IE = Nothing
        
        MsgBox "Finito!"
    End Sub

    Ho provato a cambiare TABLE in UL ma qualcosa ancora non va, e son sicuro che bisogna strutturare opportunamente il ciclo for che dovrebbe diventare da doppio a singolo.

    Chiedo quindi nuovamente aiuto a voi. Grazie a tutti per l'attenzione.

    #10986 Score: 0 | Risposta

    vecchio frac
    Senior Moderator
      272 pts

      I tag li e ul identificano gli elenchi puntati e numerati (vado a memoria). Possono stare dentro una tabella e quindi dentro una cella quindi non toglierei il riferimento nè a table nè a td e tr. Sarebbe il caso di verificare cosa restituisce Trim(tdtd.innertext) ed eventualmente splittare il risultato in corrispondenza dei relativi codici ascii che identificano l'elenco. 

      #11311 Score: 0 | Risposta

      In pratica se lascio TABLE, mi restituisce i valori presenti in fondo alla pagina internet, mentre se sostituisco TABLE con UL mi da errore di runtime 438: Proprietà o metodo non supportati dall'oggetto, bloccandosi a

      For Each trtr In myItm.Rows

      Quindi non riesco ad analizzare il Trim, in quanto il codice si blocca prima.

      Purtroppo ho carenza di nozioni sia sul html sia sul vba per capire dove sta l'inghippo... sicuramente è una sciocchezza... ma non ci arrivo da solo.

      #11326 Score: 0 | Risposta

      vecchio frac
      Senior Moderator
        272 pts

        Più sopra hai passato il link, spero di avere un attimo stasera per buttarci un occhio. Spero di poter esserti utile ma devo vedere in pratica cosa abbiamo

        #11503 Score: 0 | Risposta

        Grazie infinite per il tuo tempo... se ci sarà modo di potermi sdebitare, lo faro!   

        #11812 Score: 0 | Risposta

        Un aiutino? Non riesco proprio.

        #11832 Score: 1 | Risposta

        vecchio frac
        Senior Moderator
          272 pts

          Questo funziona sulla pagina indicata, ma su altre?

          Option Explicit
          
          Sub ProduzioneDistribuzione()
              'dichiarazione delle variabili e loro tipizzazione
              Dim IE As Object                        ' un oggetto web browser che punta a un sito
              Dim i As Long, j As Long, kk As Long    ' variabili contatori di supporto
              Dim myColl As Variant                   ' contiene il contenuto della pagina internet
              Dim myItm As Variant                    ' ogni elemento di sezione dentro la pagina internet
              Dim myURL As String                     ' indirizzo internet da raggiungere
              Dim trtr As Variant, tdtd As Variant    ' riferimenti alle righe delle tabelle della pagina internet
              Dim sections As Variant, section As Variant                 ' qui sono contenuti i titoli delle diverse sezioni,
                                                      ' che poi saranno filtrati dalla costante iniziale
              Dim v As Variant
              Const TITLES As String = "Production,Distributors"     'la costante TITLES serve da filtro per le sezioni da recuperare
              
              'imposta internet l'indirizzo da raggiungere
              myURL = "https://www.imdb.com/title/tt0227445/companycredits"
              'crea l'oggetto internet explorer
              Set IE = CreateObject("InternetExplorer.Application")
          
          
              With IE
                  .Navigate myURL
                  .Visible = True
                  Do While .Busy: DoEvents: Loop 'Attesa not busy
                  Do While .ReadyState <> 4: DoEvents: Loop 'Attesa documento
              End With
              
              Set sections = IE.Document.getElementsbyTagName("H4")
          
              Application.Goto Sheets("Importa_Produzione").Range("A1")
              ActiveSheet.UsedRange.Clear
              
              i = 0
              kk = 0
              j = 2
              Set myColl = IE.Document.getElementsbyTagName("UL")
              For Each myItm In Array(myColl(14), myColl(15))
                  For Each section In sections
                      If kk = 0 Or kk = 12 Then
                      Debug.Print kk
                          i = i + 1
                          Cells(i, "A").Value = section.innertext
                          For Each v In Split(myItm.innertext, vbLf)
                              Cells(i + 1, j) = v
                              i = i + 1
                          Next
                          j = j + 1
                      End If
                      kk = kk + 1
                  Next section
              Next myItm
              
              'operazioni finali
              Range("A1").Select
              ActiveSheet.UsedRange.WrapText = False
              
              'esce dall'applicazione internet e distrugge l'oggetto in memoria
              IE.Quit
              Set IE = Nothing
              
              MsgBox "Finito!"
          End Sub
          
          #11971 Score: 0 | Risposta

          Ciao Vecchio Frac, grazie, funziona alla grande anche su altre pagine del sito relative a Produzione e Distribuzione.

          In sostanza la pagina in questione è strutturata diversamente, chissà perché!

          Adesso, con qualche piccolo aggiustamento di codice, e una UserForm creata su misura per la cosa, potrò completare il mio "Progettino Filmografia Personale".

          Ci tengo a ringraziarti davvero per l'aiuto che mi hai dato, e ringrazio anche il creatore del sito e tutto lo staff che aiuta giornalmente persone come me che si affacciano per le prime volte alla programmazione VBA.

          Un grazie di cuore a tutti e alla prossima.

          #11975 Score: 1 | Risposta

          vecchio frac
          Senior Moderator
            272 pts

            Grazie a te per il feedback.

            Vorrei invitarti a studiarti bene il codice per capire cosa fa, riga per riga. Se hai domande, falle senza scrupoli. Il punto è che non ci sarà sempre qualcuno disposto, in futuro, a riprendere in mano del codice scritto da altri (come questo) e quindi per eventuali aggiustamenti o nuove integrazioni dovrai essere in grado di metterci le mani. 

            Ho iniziato l'anno nuovo dichiarando che avrei fatto più didattica e meno codice, in questa discussione però (iniziata nel 2018) ho voluto comunque terminare il lavoro sia per non lasciarti a piedi 🙂 che perchè effettivamente è stato abbastanza sfidante 😉

            #11977 Score: 0 | Risposta

            Giusto! Fare didattica, come anche i tuoi commenti riga per riga al codice passato, mi hanno aiutato molto.

            Sulla vecchia versione del forum, ero registrato con altro nick, ed ho chiesto altre volte il vostro aiuto, per altri piccoli progettini, proponendo sempre o quasi del codice di partenza; ho sempre visto invece molte volte, che la gente non ama applicarsi ed imparare, ma chiede "quasi" che gli venga dato del codice "bello e pronto" per i loro progetti, e questo a mio avviso non è molto bello, soprattutto per voi. Quindi, ti quoto al 100% sul: + didattica e - codice!

            Devo studiare il ciclo, e capire bene cosa fa... anche perché vedo un "Array" e un "Split", che non mastico bene ancora (e già qualche lieve spiegazione non mi farebbe male); comunque li cerco sul libro, ci studio un po, mi faccio anche un debug passo-passo per vedere esattamente cosa avviene sul foglio, e se qualcosa non mi è chiara, torno di sicuro a chiedere lumi.

            N.b.: Molto probabilmente, separerò la tua sub in due parti, una per la Produzione, e una per la Distribuzione... giusto per comodità di cose nell'ambito in cui la voglio applicare!

             

            #11978 Score: 1 | Risposta

            vecchio frac
            Senior Moderator
              272 pts

              PippoLogic80 ha scritto:

              ero registrato con altro nick

              Ah bene, e chi eri?   

              For Each myItm In Array(myColl(14), myColl(15))

              Array crea un insieme di elementi al cui interno poter effettuare operazioni, come nell'esempio in un ciclo For, ad ogni esecuzione del ciclo la variabile contatore assume il valore di ogni elemento nell'array. L'istruzione Array accetta qualsiasi tipo di dato, così Array(1, 3.5, "stringa", #15/01/2019#) raggruppa un intero, un numero con virgola, una stringa di testo e una data. Il primo elemento di un Array ha indice zero.

              For Each v In Split(myItm.innertext, vbLf)

              Split prende una stringa di testo e un delimitatore (se omesso è sottinteso il carattere spazio), e restituisce un array composto da tutti elementi della stringa che sono divisi dal delimitatore. Per esempio, v = Split("uno per tutti-tutti per uno", " ") restituisce un Array composto da 5 elementi numerati da zero a 4, per cui v(0) è il primo elemento e vale "uno" e v(2) è il terzo elemento e vale "tutti-tutti". Però v = Split("uno per tutti-tutti per uno", "-") ora separa la stringa al trattino per cui la variabile avrà solo due elementi: v(0) = "uno per tutti" e v(1) = "tutti per uno".

              Nell'esempio di cui sopra, il testo di myItm.innertext viene suddiviso in tanti pezzettini in corrispondenza dei ritorni a capo (vbLf = Linefeed) e ognuno viene assegnato alla variabile del ciclo v.

              Il contrario di Split, che serve invece ad unire gli elementi di un Array, è Join.

              #12062 Score: 0 | Risposta

              Grazie per le tue spiegazioni, chiare ed esaustive. Per la tua prima domanda, e chi legge mi scuserà, ma ti rispondo in privato   .

              #12068 Score: 0 | Risposta

              vecchio frac
              Senior Moderator
                272 pts

                PippoLogic80 ha scritto:

                Per la tua prima domanda

                Per carità, rispetto la tua privacy e se non vuoi fa niente 😀

              Login Registrati
              Stai vedendo 13 articoli - dal 26 a 38 (di 38 totali)
              Rispondi a: Importare dati in tabella excel da una pagina web
              Gli allegati sono permessi solo ad utenti REGISTRATI
              Le tue informazioni: