Risolto Problema scraping con Selenium

mibo8

Utente abituale
4 Maggio 2017
138
16
Roma
excel 2011 MAC
3
Ciao a tutti!
Data l'impossibilità di utilizzare Internet Explorer, sto cercando di capire come effettuare lo scraping da un sito web utilizzando Microsoft Edge.
Sto seguendo un tutorial sull'utilizzo di Selenium e quindi sto muovendo i primi passi.
Mi trovo però di fronte ad un problema che non riesco a superare.
Quello che vorrei far fare alla macro, in questo primo step (giusto per capirne il funzionamento), è aprire un sito web, inserire un dato specifico nella finestra di ricerca e cliccare sul pulsante "cerca".

Ho impostato la macro in questo modo ma quando faccio il debug, visualizzo l'errore "Elemento con il nome container non trovato".
Il sito in questione è il seguente: Online Container & Freight Tracking System – Searates.com

Gentilmente potreste farmi capire dove sbaglio? Potrebbe essere un problema dovuto al fatto che nel sito in questione la parola "container" viene ripetuta più volte? Ho provato a trovare altri riferimenti che indirizzassero alla finestra in questione ma non sono riuscito nell'intento...
Grazie a tutti!

Visual Basic:
Option Explicit
Private ch As Selenium.EdgeDriver

Sub Scraping()

    Set ch = New Selenium.EdgeDriver
    ch.Start baseUrl:="https://www.searates.com/container/tracking/"
    ch.Get "/"
                      
    ch.FindElementByName("container").SendKeys "GETU5933563"
    ch.FindElementByClass("panel-sector-btn").Click
    
End Sub
 

Powerwin

VBA Expert
Supermoderatore
17 Marzo 2016
8.837
245
vicino a Milano
2019 e 365
301
Ciao, non sono espertissimo neppure io ma da ispezione della pagina a mio parere dovresti cercare prima la
<div class="panel-sector code-sector search-input">
poi all'interno di quella cerchi ciò che ti serve
<input type="text" name="container" placeholder="Search"
 

mibo8

Utente abituale
4 Maggio 2017
138
16
Roma
excel 2011 MAC
3
Powerwin ha scritto:
Option Explicit
Private cd As Selenium.EdgeDriver

Sub Scraping()

Dim SearchInput As Selenium.WebElement
Set cd = New Selenium.EdgeDriver

cd.Start
cd.Get "https://www.searates.com/container/tracking/"
Set SearchInput = cd.FindElementByXPath("//*[@id='panel']/div[1]/input")
'Set SearchInput = cd.FindElementByXPath("//input[@pattern='[A-Za-z0-9]*']")
SearchInput.SendKeys "Prova"


End Sub[/CODE]
 

Rubik72

Excel/VBA Expert
Supermoderatore
12 Dicembre 2015
11.695
845
49
Cosenza
Excel 2016
984
Un saluto a tutti.
L'elemento richiesto è contenuto in un iFrame che a sua volta porta alla pagina: https://sirius.searates.com/tracking/multitracking? quindi prova con:
Visual Basic:
Option Explicit
Private ch As Selenium.EdgeDriver

Sub Scraping()

    Set ch = New Selenium.EdgeDriver
'    ch.Start baseUrl:="https://www.searates.com/container/tracking/"
    ch.Start baseUrl:="https://sirius.searates.com/tracking/multitracking?"
    ch.Get "/"
   
    ch.FindElementByName("container").SendKeys "GETU5933563"
    ch.FindElementByClass("panel-sector-btn").Click
   
End Sub
 
  • Like
Reactions: ges

ges

Excel/VBA Expert
Amministratore
21 Giugno 2015
29.816
2.465
Como
2011MAC 365WIN
1.051
Ciao a tutti,
questa discussione mi era proprio sfuggita.
Come dice Rubik72 @Rubik72 cappello_saluta, lo spazio in cui bisogna inserire il codice tracking è in un frame e si può utilizzare direttamente il link che porta l'accesso a questo, come è stato mostrato sopra.
In alternativa, siccome i frame sono delle strutture che raggruppano dei dati, cioè degli elementi che hanno un indice, si può utilizzare il metodo SwitchToFrame seguito dall'indice (in questo caso essendo l'unico è zero) che permette l'accesso al frame.
Il codice,pertanto è uguale a quello che hai postato con la'ggiunta di una riga e diventa così
Visual Basic:
Option Explicit
Private ch As Selenium.EdgeDriver

Sub Scraping()

    Set ch = New Selenium.EdgeDriver
    ch.Start baseUrl:="https://www.searates.com/container/tracking/"
    ch.Get "/"
 
    ch.SwitchToFrame (0)
    ch.FindElementByName("container").SendKeys "GETU5933563"
    ch.FindElementByClass("panel-sector-btn").Click
 
End Sub
 
Ultima modifica:
  • Like
Reactions: Rubik72

mibo8

Utente abituale
4 Maggio 2017
138
16
Roma
excel 2011 MAC
3
Grazie a tutti per le risposte e l'aiuto!!
Non avrei mai trovato l'iframe! :occhispalancati:

Ho sviluppato la macro in modo che, inserendo una serie di codici in una tabella, per ognuno venga effettuata la ricerca sul sito web in questione e vengano esportati due dati: il nome del porto e la data di arrivo prevista.

Ne approfitto per chiedere un vostro parere riguardo a due questioni:

Una volta che la macro inserisce il dato sul sito web e clicca sul pulsante "panel-sector-btn", il tempo di attesa (prima che il sito web effettui la ricerca e mostri i risultati) varia.
Nella macro in questione ho impostato 25 secondi di attesa ma potrebbero volercene di più o di meno.
Secondo voi è possibile fare in modo che la macro definisca quel tempo in automatico?

Ho notato che, utilizzando Selenium, l'istruzione .Visible = False (per nascondere la pagina web durante la ricerca) non funziona. Avete qualche suggerimento in merito?

Come sempre, grazie a tutti!!

Visual Basic:
Sub Scraping()

    Dim ch As New Selenium.EdgeDriver

    With ch
    lin = 4
    Do While Foglio1.Cells(lin, "B") <> ""
    
        .Get "https://sirius.searates.com/tracking/multitracking?"
        Application.Wait (Now + TimeValue("00:00:03"))
        .FindElementByName("container").SendKeys (Foglio1.Cells(lin, "B"))
        .FindElementByClass("panel-sector-btn").Click
        Application.Wait (Now + TimeValue("00:00:25"))
        Porto = .FindElementByXPath("//div[@class='destination-point end-point']").Text
        Data = .FindElementByXPath("//div[@class='bl-finish-date etd']").Text
        
        Foglio1.Cells(lin, "D") = Porto
        Foglio1.Cells(lin, "E") = Data
    
    lin = lin + 1
    Loop
    
   End With
   MsgBox "Import concluso", vbInformation + vbOKOnly
End Sub
 

Rubik72

Excel/VBA Expert
Supermoderatore
12 Dicembre 2015
11.695
845
49
Cosenza
Excel 2016
984
Ciao, per quanto riguarda l'attesa di caricamento puoi usare questo comando che attende finché l'oggetto non è caricato:
Visual Basic:
cd.FindElementByCss("#Departures").WaitDisplayed
mentre per la visualizzazione nascosta:
Visual Basic:
cd.AddArgument ("--headless")
 

mibo8

Utente abituale
4 Maggio 2017
138
16
Roma
excel 2011 MAC
3
Ciao Rubik, grazie per la risposta!
Ho provato ad inserire entrambi i codici ma sto sicuramente sbagliando qualcosa!

Ho inserito il codice ma la pagina web continua ad essere visibile.
(In entrambi i codici ho sostituito "cd" con "ch").
 

ges

Excel/VBA Expert
Amministratore
21 Giugno 2015
29.816
2.465
Como
2011MAC 365WIN
1.051
Scrivi qui le prime righe del codice

EDIT: Ho capito stai usando Edge e purtroppo non supporta la modalità "Headless" in Selenium.
Devi usare Chrome!
 
Ultima modifica:

mibo8

Utente abituale
4 Maggio 2017
138
16
Roma
excel 2011 MAC
3
Scrivi qui le prime righe del codice

EDIT: Ho capito stai usando Edge e purtroppo non supporta la modalità "Headless" in Selenium.
Devi usare Chrome!
Ciao Ges! cappello_saluta
Ho provveduto ad installare i driver di Chrome ed ora sto usando quel browser.
La modalità "headless" funziona alla perfezione!
Sto solo riscontrando problemi riguardo l'attesa di caricamento della pagina.
Utilizzando
Visual Basic:
Application.Wait (Now + TimeValue("00:00:25"))
la pagina viene caricata correttamente. Il problema è che a volte, dopo 5 secondi di attesa, la pagina web mostra già i risultati.
Utilizzando invece
Visual Basic:
 .FindElementByXPath("//div[@class='destination-point end-point']").WaitDisplayed
,
la macro non attende nemmeno un secondo.

Ho provato ad utilizzare anche il codice suggerito da Rubik
Visual Basic:
.FindElementByCss("#Departures").WaitDisplayed
ma visualizzo il messaggio di errore "elemento non trovato".

Qui il codice completo! Grazie a tutti per l'aiuto!

Visual Basic:
Sub Scraping()

    Dim ch As New Selenium.ChromeDriver
    
    With ch
    lin = 4
    Do While Foglio1.Cells(lin, "B") <> ""
    
        .AddArgument ("--headless")
        .Get "https://sirius.searates.com/tracking/multitracking?"
        Application.Wait (Now + TimeValue("00:00:03"))
        .FindElementByName("container").SendKeys (Foglio1.Cells(lin, "B"))
        .FindElementByClass("panel-sector-btn").Click
        'Application.Wait (Now + TimeValue("00:00:25"))
        .FindElementByXPath("//div[@class='destination-point end-point']").WaitDisplayed
        Porto = .FindElementByXPath("//div[@class='destination-point end-point']").Text
        ETA = .FindElementByXPath("//div[@class='bl-finish-date etd']").Text
        
        Foglio1.Cells(lin, "F") = Porto
        Foglio1.Cells(lin, "G") = ETA

    lin = lin + 1
    Loop
    
   End With
   MsgBox "Import concluso", vbInformation + vbOKOnly
End Sub
 

Rubik72

Excel/VBA Expert
Supermoderatore
12 Dicembre 2015
11.695
845
49
Cosenza
Excel 2016
984
Ho provato ad utilizzare anche il codice suggerito da Rubik
Visual Basic:
.FindElementByCss("#Departures").WaitDisplayed
ma visualizzo il messaggio di errore "elemento non trovato".
L'elemento suggerito era di esempio! Bisogna scrivere l'elemento che c'è nella tua pagina
 

mibo8

Utente abituale
4 Maggio 2017
138
16
Roma
excel 2011 MAC
3
[...]

Mi scuso per la svista! Essendo poco esperto credevo che il codice fosse relativo a qualche elemento presente nel codice del sito web!

Ho provato in vari modi, sia tramite .FindElementByXPath che tramite .FindElementByCss.
In entrambi i casi la macro non aspetta il caricamento della pagina web. Il debug non restituisce errori ma ovviamente sul foglio excel viene riportato "Data not found".
 

Rubik72

Excel/VBA Expert
Supermoderatore
12 Dicembre 2015
11.695
845
49
Cosenza
Excel 2016
984
Purtroppo non avendo la linea da cercare, NON possiamo verificare la comparsa dell'elemento voluto.
Indica un carico ancora in transito
 

ges

Excel/VBA Expert
Amministratore
21 Giugno 2015
29.816
2.465
Como
2011MAC 365WIN
1.051
Giusto per fare un tentativo, prova così
Visual Basic:
Sub Scraping()

    Dim ch As New Selenium.ChromeDriver
    Dim FindBy As New Selenium.By
    With ch
        lin = 4
        Do While Foglio1.Cells(lin, "B") <> ""
            bln = False
            .Start
            .AddArgument ("--headless")
            .Get "https://sirius.searates.com/tracking/multitracking?"
            Application.Wait (Now + TimeValue("00:00:03"))
            .FindElementByName("container").SendKeys (Foglio1.Cells(lin, "B"))
            .FindElementByClass("panel-sector-btn").Click
            If .IsElementPresent(FindBy.XPath("//div[@class='destination-point end-point']")) Then
                .FindElementByXPath("//div[@class='destination-point end-point']").WaitDisplayed
            End If
            If .IsElementPresent(FindBy.XPath("//div[@class='destination-point end-point']")) Then
                Porto = .FindElementByXPath("//div[@class='destination-point end-point']").Text
                bln = True
            End If
            If .IsElementPresent(FindBy.XPath("//div[@class='bl-finish-date etd']")) Then
                ETA = .FindElementByXPath("//div[@class='bl-finish-date etd']").Text
            End If
            If bln = False Then
                Foglio1.Cells(lin, "F") = Porto
                Foglio1.Cells(lin, "G") = ETA
            Else
                Foglio1.Cells(lin, "F") = "Dato non presente"
            End If
            lin = lin + 1
        Loop
    
    End With
    MsgBox "Import concluso", vbInformation + vbOKOnly
End Sub
 

mibo8

Utente abituale
4 Maggio 2017
138
16
Roma
excel 2011 MAC
3
Grazie per l'aiuto Ges!
Solito problema, la macro apre la pagina web, la chiude immediatamente e mostra il risultato "Dato non presente".
Stavo riflettendo su una possibile soluzione (dall'alto della mia quasi ignoranza in materia, ovviamente).
Effettuando una ricerca sul sito in questione, ho visto che - a seguito del click sul pulsante "Search"- appare un preloader che, ispezionando il sito web, ha il seguente codice:
Visual Basic:
<div class="preloader">
    <div>::before</div>
    <div>::before</div>
</div>
Nel momento in cui la ricerca è terminata (ed i dati vengono mostrati), il preloader scompare ed il codice diventa il seguente:
Visual Basic:
<div class="preloader">
    <div></div>
    <div></div>
</div>
Quindi mi domandavo se potesse esserci un modo per sfruttare tutto ciò...:dubbioso:
 

ges

Excel/VBA Expert
Amministratore
21 Giugno 2015
29.816
2.465
Como
2011MAC 365WIN
1.051
Scusate ma temo di non aver capito: il problema si presenta perché manca il dato oppure perché la pagina si carica troppo lentamente e non legge il dato sebbene esista.
 

mibo8

Utente abituale
4 Maggio 2017
138
16
Roma
excel 2011 MAC
3
Scusate ma temo di non aver capito: il problema si presenta perché manca il dato oppure perché la pagina si carica troppo lentamente e non legge il dato sebbene esista.
Una volta che la macro inserisce il parametro di ricerca nell'apposita finestra sul sito web e clicca sul pulsante "Search", il sito web inizia la ricerca. A ricerca terminata, appare una finestra con all'interno i dati che la macro deve riportare sul mio foglio excel.
Il problema è che il sito web impiega un tempo differente a cercare e mostrare i risultati, a seconda del parametro inserito nella finestra.
Per essere il più chiaro possibile:
La macro deve effettuare due ricerche: "PROVA" e "CIAO".
Inserendo nella finestra "PROVA", il sito web potrebbe mostrare il risultato di ricerca in 10 secondi.
Inserendo nella finestra "CIAO", il sito web potrebbe mostrare il risultato di ricerca in 30 secondi.
Quindi, per rispondere alla tua domanda, il dato (class='destination-point end-point' e class='bl-finish-date etd') non è presente fino a quando il sito web non ha completato la ricerca.
 

ges

Excel/VBA Expert
Amministratore
21 Giugno 2015
29.816
2.465
Como
2011MAC 365WIN
1.051
Facciamo un'altra prova così
Visual Basic:
Sub Scraping()

    Dim ch As New Selenium.ChromeDriver
    Dim FindBy As New Selenium.By
    Dim iTime As Integer
    With ch
        lin = 4
        Do While Foglio1.Cells(lin, "B") <> ""
            bln = False
           ' .Start
            .AddArgument ("--headless")
            .Get "https://sirius.searates.com/tracking/multitracking?"
            Application.Wait (Now + TimeValue("00:00:03"))
            .FindElementByName("container").SendKeys (Foglio1.Cells(lin, "B"))
            .FindElementByClass("panel-sector-btn").Click
            iTime = 1
            Do While iTime < 60
            .Wait 4000
            If .IsElementPresent(FindBy.Css(".bl-start-date")) Then
                Porto = .FindElementByCss(".bl-start-date").Text
                bln = True
            End If
            If bln = True Then Exit Do
            iTime = iTime + 1
            Loop
            bln = False
             iTime = 1
            Do While iTime < 60
            .Wait 4000
            If .IsElementPresent(FindBy.Css(".bl-finish-date")) Then
                ETA = .FindElementByCss(".bl-finish-date").Text
                bln = True
            End If
            If bln = True Then Exit Do
            iTime = iTime + 1
            Loop
            
            If bln = True Then
                Foglio1.Cells(lin, "F") = Porto
                Foglio1.Cells(lin, "G") = ETA
            Else
                Foglio1.Cells(lin, "F") = "Dato non presente"
            End If
            lin = lin + 1
        Loop
    
    End With
    MsgBox "Import concluso", vbInformation + vbOKOnly
End Sub
 
Ultima modifica:

mibo8

Utente abituale
4 Maggio 2017
138
16
Roma
excel 2011 MAC
3
Facciamo un'altra prova così
Visual Basic:
Sub Scraping()

    Dim ch As New Selenium.ChromeDriver
    Dim FindBy As New Selenium.By
    Dim iTime As Integer
    With ch
        lin = 4
        Do While Foglio1.Cells(lin, "B") <> ""
            bln = False
           ' .Start
            .AddArgument ("--headless")
            .Get "https://sirius.searates.com/tracking/multitracking?"
            Application.Wait (Now + TimeValue("00:00:03"))
            .FindElementByName("container").SendKeys (Foglio1.Cells(lin, "B"))
            .FindElementByClass("panel-sector-btn").Click
            iTime = 1
            Do While iTime < 60
            .Wait 4000
            If .IsElementPresent(FindBy.Css(".bl-start-date")) Then
                Porto = .FindElementByCss(".bl-start-date").Text
                bln = True
            End If
            If bln = True Then Exit Do
            iTime = iTime + 1
            Loop
            bln = False
             iTime = 1
            Do While iTime < 60
            .Wait 4000
            If .IsElementPresent(FindBy.Css(".bl-finish-date")) Then
                ETA = .FindElementByCss(".bl-finish-date").Text
                bln = True
            End If
            If bln = True Then Exit Do
            iTime = iTime + 1
            Loop
          
            If bln = True Then
                Foglio1.Cells(lin, "F") = Porto
                Foglio1.Cells(lin, "G") = ETA
            Else
                Foglio1.Cells(lin, "F") = "Dato non presente"
            End If
            lin = lin + 1
        Loop
  
    End With
    MsgBox "Import concluso", vbInformation + vbOKOnly
End Sub
Ciao Ges,

come sempre ti ringrazio per la risposta!
Ho provato il codice ma è ancora presente lo stesso errore.
La macro a volte "non attende" il risultato della ricerca sulla pagina web e riporta, sul foglio excel, la scritta "risultato non trovato".
 

ges

Excel/VBA Expert
Amministratore
21 Giugno 2015
29.816
2.465
Como
2011MAC 365WIN
1.051
Dove si presenta l'errore esattamente? E la variabile iTime quanto è valorizzata al momento dell'errore?
 

Sostieni ForumExcel

Aiutaci a sostenere le spese e a mantenere online la community attraverso una libera donazione!