estrazione dati da web



  • estrazione dati da web
    di accordix (utente non iscritto) data: 07/03/2014 12:12:22

    Premetto che on ho mai interfacciato excel al web e non saprei da dove cominciare.

    Avrei bisogno di estrarre dei dati da una pagina web su intranet (devo gestire orario ingresso e uscita del personale) e leggendo il sorgente della pag web vedo che i dati sono messi cosi

    dato che mi serve

    da dire alcune cose su questa pag web
    i campi sono 5
    NUM, cognome,nome, inizio,fine
    ripetuto per 'n' persone

    ctl00_ContentPlaceHolder1_GridView1_ctl02_NUM
    ctl00_ContentPlaceHolder1_GridView1_ctl02_cognome
    ctl00_ContentPlaceHolder1_GridView1_ctl02_nome
    ctl00_ContentPlaceHolder1_GridView1_ctl02_inizio
    ctl00_ContentPlaceHolder1_GridView1_ctl02_fine

    per record successivo aumenta 'ctl02' di 1 fino a tutto il personale

    il risultato poi viene gestito da una procedura esistente in vba in quanto fino a ora sono inseriti manualmente in un form di inserimento.

    come potrei procedere?



  • di accordix data: 07/03/2014 12:36:10

    Premetto che on ho mai interfacciato excel al web e non saprei da dove cominciare.

    Avrei bisogno di estrarre dei dati da una pagina web su intranet (devo gestire orario ingresso e uscita del personale) e leggendo il sorgente della pag web vedo che i dati sono messi cosi (vedi codice)



    da dire alcune cose su questa pag web
    i campi sono 5
    NUM, cognome,nome, inizio,fine
    ripetuto per 'n' persone

    ctl00_ContentPlaceHolder1_GridView1_ctl02_NUM
    ctl00_ContentPlaceHolder1_GridView1_ctl02_cognome
    ctl00_ContentPlaceHolder1_GridView1_ctl02_nome
    ctl00_ContentPlaceHolder1_GridView1_ctl02_inizio
    ctl00_ContentPlaceHolder1_GridView1_ctl02_fine

    per record successivo aumenta 'ctl02' di 1 fino a tutto il personale

    il risultato poi viene gestito da una procedura esistente in vba in quanto fino a ora sono inseriti manualmente in un form di inserimento.

    come potrei procedere?
     
    span id="ctl00_ContentPlaceHolder1_GridView1_ctl02_cognome" style="display:inline-block;background-color:Transparent;border-color:Transparent;border-width:0px;border-style:None;">dato da estrarre"/span
                             



  • di scossa data: 07/03/2014 13:11:23

    Ciao,

    1) Sarebbe molto più semplice se ti facessi autorizzare ad accedere alla sottostante tabella del db.

    2) dovresti postare (magari come allegato .txt) il sorgente della pagina html (camuffando i soli dati sensibili) che comprenda almeno 3 nominativi.




  • di accordix (utente non iscritto) data: 07/03/2014 13:43:31

    mandato il file



  • di accordix (utente non iscritto) data: 07/03/2014 14:16:19

    mandato il file pippo1.txt


  • ignorate questo messaggio
    di Luca.Donati data: 07/03/2014 16:17:48

    Ciao. Solo per dire che l'argomento interessa anche me (e così ricevo una notifica).



  • di Mauro data: 07/03/2014 21:40:09

    Il file è stato rimosso, come da richiesta.



  • di accordix (utente non iscritto) data: 07/03/2014 21:52:39

    ne vedo ancora in giro di file pippo1.txt
    se li togli metto quello buono
    grazie



  • di accordix data: 08/03/2014 14:08:10

    inviato nuovo file senza dati sensibili
    scusate per il contrattempo pensavo di aver pulito tutto
    cmq se qualcuno puo darmi qualche input su come agire lo ringrazio gia da adesso



  • di accordix data: 11/03/2014 16:16:13

    nessuna idea al riguardo?

    ho trovato qualcosa ma non posso provare almeno fino a lunedi prossimo in quanto mi so beccato influenza
    e non trovo nessun sito che pubblichi tabelle con span (mica sto dicendo eresie? -.-)

    Set MySpan = ieDoc.getElementsByTagName("span")
    con questo punto al tag poi dovrei prendere il dato che mi interessa .....



  • di scossa data: 12/03/2014 17:39:02

    Adatta questo codice, ora l'ho impostato per "www.google.com", ma basta che cambi la costante

    Const sWeb As String = "www.google.com"

    con l'indirizzo della tua pagina e che commenti la riga

    Const sID = "footer"

    attivando al suo posto

    Const sID = "_ContentPlaceHolder1_GridView1_ct"


    Ovviamente dovrai gestire diversamente gli elementi trovati.


     
    Sub SpanHTML()
      'by scossa
    
      Dim ie As Object
      Dim ie_Element As Object
      Dim nLoops As Long
      Const sWeb As String = "www.google.com" 'sostituire con il tuo indirizzo web 
      'Const sID = "_ContentPlaceHolder1_GridView1_ct" ' attivare al posto di quella sotto
      Const sID = "footer"
      
      Set ie = CreateObject("InternetExplorer.Application")
      
      With ie
        .Silent = True
        .navigate sWeb
        .Visible = False
        Application.Wait Now + TimeValue("0:00:03")
        nLoops = 0
        Do Until .ReadyState = 4
          DoEvents
          nLoops = nLoops + 1
          If nLoops > 50000 Then
            Err.Raise vbObjectError + 513, , "Il server non risponde"
          End If
        Loop
        For Each ie_Element In .document.getElementsByTagName("SPAN")
          Debug.Print ie_Element.ID
          If InStr(ie_Element.ID, sID) > 0 Then
            MsgBox ie_Element.outerHTML 'sostituire con il tuo codice per gestire i singoli elementi
          End If
        Next
        .Quit
      End With



  • di accordix data: 16/03/2014 20:43:11

    Caro scossa avevo scritto precedentemente che questa procedura la potro verificare solo domani visto che so stato tutta la settimana a letto con influenza, per cui non capisco lo sfogo che hai fatto su altro thread. Cmq pensavo che visto che la pag che dovro visistare e' una pag protetta come faccio con il login?

    a questo non ci avevo pensato -.-



  • di scossa data: 16/03/2014 21:08:29

    cit.: "avevo scritto precedentemente che questa procedura la potro verificare solo domani"
    Cerchiamo di non fare confusione tra quello che si pensa e quello che si dice.
    Tu non hai risposto a me, visto che
    "ho trovato qualcosa ma non posso provare almeno fino a lunedi prossimo in quanto mi so beccato influenza"
    lo hai scritto prima del mio intervento.
    Se tu avessi dato un cenno di riscontro quando hai letto la mia proposta (come ti sei premurato di fare adesso leggendo l'altro post), non avrei avuto la sgradevole sensazione di aver perso tempo.



  • di accordix (utente non iscritto) data: 16/03/2014 21:39:46

    Hai ragione, scusa tanto



  • di scossa data: 16/03/2014 21:58:14

    cit.: "pensavo che visto che la pag che dovro visistare e' una pag protetta come faccio con il login?"

    Se quel sito ti permette di "ricordarti" potresti loggarti prima di fare eseguire la macro.
    Altrimenti bisogna vedere il sorgente della pagina con cui ti chiede il login ....



  • di accordix (utente non iscritto) data: 17/03/2014 15:46:43

    Finalmente ho potuto usare la procedura e fare le opportune verifiche.
    Funziona che e' na meraviglia e su questo non avevo dubbi. Quello che non riesco a capire e' questo:
    i dati li prendo con una chiamata innerHTML; ora se metto il contenuto in una cella del foglio no problem ma se voglio mettere in un variabile mi dice tipo non corrispondente.
    Perche mi succede questo?

    ti allego il file che ho fatto di prova

    p.s. non serve il login lo ricorda gia



  • di Vecchio Frac data: 17/03/2014 18:05:15

    cit. " ma se voglio mettere in un variabile mi dice tipo non corrispondente."
    ---> Bè, ma come è dichiarata la variabile?
    Se la dichiari Long e tenti di metterci dentro una stringa, ottieni quell'errore ^_^
    Per sicurezza dichiarala As Variant e al 99% dovresti essere a posto.
    Excel in una cella del foglio ci fa stare dentro di tutto.





  • di lepat (utente non iscritto) data: 17/03/2014 18:40:17

    cit.
    p.s. non serve il login lo ricorda già

    lo ricorda sul tuo pc, ma non in quello degli altri



  • di accordix (utente non iscritto) data: 17/03/2014 19:04:25

    x Vecchio Frac; provato sia string che variant ma mi da errore
    x lepat ; non mi serve che ricordi su altri pc visto che cmq su quella pag ci posso accedere solo io e solo da quel pc, e' una postazione intranet con tanti limiti -.-



  • di scossa data: 17/03/2014 21:23:31

    il codice sotto riportato estrae (sul Foglio2) i dati richiesti (num cognome nome inizio fine) dalla tua pagina web, sfruttando i tag e le regular-expression.

    N.B.: sostituisci "####://scossavr.altervista.org/Downloads/Excel/filebuono.html" con l'indirizzo web della tua pagina (#### = il solito accatitipi)
     
    Sub ParseHTMLRegEx()
      Dim wb As Workbook
      Dim ws As Worksheet
      Dim cella As Range
      Dim ie As Object
      Dim ie_Element As Object
      Dim nLoops As Long
      Dim re As Object
      Dim reMatch As Variant
      Dim nItems As Long
      Dim j As Long
      Dim nStart As Long
      Dim nEnd As Long
      Dim sTesto As String
      Dim sParsed As String
      Dim sToken As String
      Dim sPatt As String
        
      Const sWeb As String = "####://scossavr.altervista.org/Downloads/Excel/filebuono.html" 'sostituire con il tuo indirizzo web
      Const sID = "_ContentPlaceHolder1_GridView1_ct"
      On Error GoTo parseHTML_Error
      Set wb = ThisWorkbook
      Set ws = wb.Worksheets("Foglio2")
      Set re = CreateObject("vbscript.regexp")
      Set ie = CreateObject("InternetExplorer.Application")
      
      With ie
        .Silent = True
        .Visible = True
        .navigate sWeb
        Application.Wait Now + TimeValue("0:00:03")
        nLoops = 0
        Do Until .ReadyState = 4
          DoEvents
          nLoops = nLoops + 1
          If nLoops > 50000 Then
            Err.Raise vbObjectError + 513, , "Il server non risponde"
          End If
        Loop
        sTesto = .document.body.innerHTML
      End With
      ie.Quit
      
      With re
        .Global = True
        .IgnoreCase = True
        '---------  NUM  ----------------------------
        Set cella = ws.Cells(ws.Cells(Rows.Count, 1).End(xlUp).Row + 1, 1)
        sPatt = "GridView1_ctldd_NUM>"
        .Pattern = sPatt
        Set reMatch = .Execute(sTesto)
        With reMatch
          nItems = .Count
          If nItems > 0 Then
            For j = 0 To nItems - 1
              nStart = .item(j).Firstindex + .item(j).Length + 1
              nEnd = InStr(nStart, sTesto, "", vbTextCompare)
              sParsed = Mid(sTesto, nStart, nEnd - nStart)
                cella.Value = sParsed
                Set cella = cella.Offset(1, 0)
            Next
          End If
        End With
        
        '---------  cognome  ----------------------------
        Set cella = ws.Cells(ws.Cells(Rows.Count, 2).End(xlUp).Row + 1, 2)
        sPatt = "GridView1_ctldd_cognome>"
        .Pattern = sPatt
        Set reMatch = .Execute(sTesto)
        With reMatch
          nItems = .Count
          If nItems > 0 Then
            For j = 0 To nItems - 1
              nStart = .item(j).Firstindex + .item(j).Length + 1
              nEnd = InStr(nStart, sTesto, "", vbTextCompare)
              sParsed = Mid(sTesto, nStart, nEnd - nStart)
                cella.Value = sParsed
                Set cella = cella.Offset(1, 0)
              'End If
            Next
          End If
        End With
      
        '---------  nome  ----------------------------
        Set cella = ws.Cells(ws.Cells(Rows.Count, 3).End(xlUp).Row + 1, 3)
        sPatt = "GridView1_ctldd_nome>"
        .Pattern = sPatt
        Set reMatch = .Execute(sTesto)
        With reMatch
          nItems = .Count
          If nItems > 0 Then
            For j = 0 To nItems - 1
              nStart = .item(j).Firstindex + .item(j).Length + 1
              nEnd = InStr(nStart, sTesto, "", vbTextCompare)
              sParsed = Mid(sTesto, nStart, nEnd - nStart)
              'If sParsed <> "" Then
                cella.Value = sParsed
                Set cella = cella.Offset(1, 0)
            Next
          End If
        End With
      
        '---------  inizio  ----------------------------
        Set cella = ws.Cells(ws.Cells(Rows.Count, 4).End(xlUp).Row + 1, 4)
        sPatt = "GridView1_ctldd_inizio>"
        .Pattern = sPatt
        Set reMatch = .Execute(sTesto)
        With reMatch
          nItems = .Count
          If nItems > 0 Then
            For j = 0 To nItems - 1
              nStart = .item(j).Firstindex + .item(j).Length + 1
              nEnd = InStr(nStart, sTesto, "", vbTextCompare)
              sParsed = Mid(sTesto, nStart, nEnd - nStart)
                cella.Value = sParsed
                Set cella = cella.Offset(1, 0)
            Next
          End If
        End With
      
        '---------  termine  ----------------------------
        Set cella = ws.Cells(ws.Cells(Rows.Count, 5).End(xlUp).Row + 1, 5)
        sPatt = "GridView1_ctldd_termine>"
        .Pattern = sPatt
        Set reMatch = .Execute(sTesto)
        With reMatch
          nItems = .Count
          If nItems > 0 Then
            For j = 0 To nItems - 1
              nStart = .item(j).Firstindex + .item(j).Length + 1
              nEnd = InStr(nStart, sTesto, "", vbTextCompare)
              sParsed = Mid(sTesto, nStart, nEnd - nStart)
                cella.Value = sParsed
                Set cella = cella.Offset(1, 0)
            Next
          End If
        End With
      
      
      
      End With
    
    
    parseHTML_Error:
      Set cella = Nothing
      Set ws = Nothing
      Set wb = Nothing
      Set re = Nothing
      Set reMatch = Nothing
      Set ie = Nothing
      If Err.Number <> 0 Then
        MsgBox "Error: " & Err.Description, vbCritical, "ERRORE"
      Else
          MsgBox "Elaborazione Terminata", vbInformation
      End If
      
    End Sub
    
    
    Sub ParseHTML()
      Dim wb As Workbook
      Dim ws As Worksheet
      Dim cella As Range
      Dim ie As Object
      Dim ie_Element As Object
      Dim nLoops As Long
      Dim re As Object
      Dim reMatch As Variant
      Dim nItems As Long
      Dim j As Long
      Dim nStart As Long
      Dim nEnd As Long
      Dim sTesto As String
      Dim sParsed As String
      Dim sToken As String
      Dim sPatt As String
        
      Const sWeb As String = "h##p://scossavr.altervista.org/Downloads/Excel/filebuono.html" 'sostituire con il tuo indirizzo web
      Const sID = "_ContentPlaceHolder1_GridView1_ct" ' attivare al posto di quella sotto
      'Const sID = "footer"
      
      On Error GoTo parseHTML_Error
      Set wb = ThisWorkbook
      Set ws = wb.Worksheets("Foglio2")
      Set re = CreateObject("vbscript.regexp")
      Set ie = CreateObject("InternetExplorer.Application")
      Set cella = ws.Cells(ws.Cells(Rows.Count, 1).End(xlUp).Row, 1)
      With ie
        .Silent = True
        .Visible = False 'True
        .navigate sWeb
        Application.Wait Now + TimeValue("0:00:03")
        nLoops = 0
        Do Until .ReadyState = 4
          DoEvents
          nLoops = nLoops + 1
          If nLoops > 50000 Then
            Err.Raise vbObjectError + 513, , "Il server non risponde"
          End If
        Loop
        'sTesto = .document.body.innerHTML
        For Each ie_Element In .document.getElementsByTagName("SPAN")
          Debug.Print ie_Element.ID
          Select Case True
            Case InStr(1, ie_Element.ID, "_NUM", vbBinaryCompare) > 0
              sTesto = ie_Element.innerText
              j = j + 1
              cella.Offset(j, 0).Value = sTesto
            Case InStr(1, ie_Element.ID, "_cognome", vbBinaryCompare) > 0
              sTesto = ie_Element.innerText
              cella.Offset(j, 1).Value = sTesto
            Case InStr(1, ie_Element.ID, "_nome", vbBinaryCompare) > 0
              sTesto = ie_Element.innerText
              cella.Offset(j, 2).Value = sTesto
            Case InStr(1, ie_Element.ID, "_inizio", vbBinaryCompare) > 0
              sTesto = ie_Element.innerText
              cella.Offset(j, 3).Value = sTesto
            Case InStr(1, ie_Element.ID, "_termine", vbBinaryCompare) > 0
              sTesto = ie_Element.innerText
              cella.Offset(j, 4).Value = sTesto
          End Select
        Next
      End With
      ie.Quit
    
    parseHTML_Error:
      Set cella = Nothing
      Set ws = Nothing
      Set wb = Nothing
      Set re = Nothing
      Set reMatch = Nothing
      Set ie = Nothing
      If Err.Number <> 0 Then
        MsgBox "Error: " & Err.Description, vbCritical, "ERRORE"
      Else
          MsgBox "Elaborazione Terminata", vbInformation
      End If
      
    End Sub
    



  • di scossa data: 17/03/2014 21:26:45

    attenzione: nel post sopra il codice è ripetuto due volte!!!



  • di accordix (utente non iscritto) data: 17/03/2014 23:53:02

    tutto cio per estrarre i dati dalla pagina odierna; e se volessi estrarre in base a una data?
    sulla pag ci sta un calendario, viene gestito come? si riesce a vedere dal sorgente?



  • di scossa data: 18/03/2014 09:47:59

    Questo invece un codice che utilizza l'attributo Id e senza regex.
     
    Sub ParseHTMLbyID()
      Dim wb As Workbook
      Dim ws As Worksheet
      Dim cella As Range
      Dim ie As Object
      Dim ie_Element As Object
      Dim nLoops As Long
      Dim j As Long
      Dim sTesto As String
        
      Const sWeb As String = "scossavr.altervista.org/Downloads/Excel/orari.html" 'sostituire con il tuo indirizzo web
      Const sID = "_ContentPlaceHolder1_GridView1_ct" ' attivare al posto di quella sotto
      
      On Error GoTo ParseHTMLbyID_Error
      Set wb = ThisWorkbook
      Set ws = wb.Worksheets("Foglio2")
      Set ie = CreateObject("InternetExplorer.Application")
      
      With ie
        .Silent = True
        .Visible = False
        .navigate sWeb
        Application.Wait Now + TimeValue("0:00:03")
        nLoops = 0
        Do Until .ReadyState = 4
          DoEvents
          nLoops = nLoops + 1
          If nLoops > 50000 Then
            Err.Raise vbObjectError + 513, , "Il server non risponde"
          End If
        Loop
        Set cella = ws.Cells(ws.Cells(Rows.Count, 1).End(xlUp).Row + 1, 1)
        For Each ie_Element In .document.getElementById("ctl00_ContentPlaceHolder1_GridView1").all
          Debug.Print ie_Element.ID
          If ie_Element.ID Like "*_NUM" Then
            cella.Offset(0, 0).Value = ie_Element.innerText
          ElseIf ie_Element.ID Like "*_cognome" Then
            cella.Offset(0, 1).Value = ie_Element.innerText
          ElseIf ie_Element.ID Like "*_nome" Then
            cella.Offset(0, 2).Value = ie_Element.innerText
          ElseIf ie_Element.ID Like "*_inizio" Then
            cella.Offset(0, 3).Value = ie_Element.innerText
          ElseIf ie_Element.ID Like "*_termine" Then
            cella.Offset(0, 4).Value = ie_Element.innerText
            Set cella = cella.Offset(1, 0)
          End If
        Next
      End With
    
    ParseHTMLbyID_Error:
      Set cella = Nothing
      Set ws = Nothing
      Set wb = Nothing
      If Err.Number <> 0 Then
        MsgBox "Error: " & Err.Description, vbCritical, "ERRORE"
      Else
          MsgBox "Elaborazione Terminata", vbInformation
      End If
      On Error Resume Next
      ie.Quit
      Set ie = Nothing
    
    End Sub
    



  • di scossa data: 18/03/2014 11:50:48

    cit. accordix: " e se volessi estrarre in base a una data? "

    Non posso testarlo in quanto agisce solo sulla pagina web reale, ma prova ad inserire nella macro che ho postato per ultima, il codice sotto riportato, prima della riga:

    Set cella = ws.Cells(ws.Cells(Rows.Count, 1).End(xlUp).Row + 1, 1)

    in A1 del foglio2 scrivi la tua data e poi lancia la macro.
     
        '---------------------- scelta data -------------------------
        'ovviamente agisce solo sulla pagina web reale
        '
        'il valore per __EVENTARGUMENT è:
        'la tua data Excel - 36526
        '04/03/2014 = 41702 - 36526 = 5176
        '
        nData = ws.Range("A1") - 36526
        .Document.getElementById("__EVENTTARGET").Value = "ctl00$ContentPlaceHolder1$Calendar1"
        .Document.getElementById("__EVENTARGUMENT").Value = nData
        .Document.getElementById("aspnetForm").submit
        
        Application.Wait Now + TimeValue("0:00:02")
        DoEvents
        Do Until .ReadyState = 4
          DoEvents
          nLoops = nLoops + 1
          If nLoops > 50000 Then
            Err.Raise vbObjectError + 513, , "Il server non risponde"
          End If
        Loop
        '---------------------- fine scelta data -------------------------
        
    



  • di accordix (utente non iscritto) data: 19/03/2014 23:03:34

    le prime 2 procedure; la ParseHTML funge ma alla fine mi da erroroe tipo non corrispondente

    la ParseHTMLRegEx mi da errore tipo non corrispondente ma nessun output
    Domani provo l'altra e ti faccio sapere



  • di accordix (utente non iscritto) data: 20/03/2014 15:40:57

    Funziona tutto anche per le date antecedenti. L'unica cosa che non riesco a capire e' che alla fine mi da un errore "Indice non incluso nell'intervallo",perche fa questo?
    togliendo la gestione errori sembra funzionare bene



  • di scossa data: 20/03/2014 19:43:04

    cit.: "L'unica cosa che non riesco a capire e' che alla fine mi da un errore "Indice non incluso nell'intervallo",perche fa questo?
    togliendo la gestione errori sembra funzionare bene"

    Non saprei dirti, senza accedere alla pagina web reale, anche perché a me con la pagina test funziona sia su IE8 che IE11.



  • di accordix (utente non iscritto) data: 24/03/2014 15:55:26

    a parte quel problema (risolto momentaneamente togliendo la gestione errori) la procedura funziona per cui metto "risolto"