› Excel e gli applicativi Microsoft Office › Selenium x selezione Pagine
-
AutoreArticoli
-
Cia ragazzi ,mi sono bloccato in una procedura per lo scarico dati da un sito , ovvero ho il problema di selezionare le pagine successive alla prima, ma non riesco a trovare il percorso corretto (css o Xpath o class che sia ) Se quulacuno volesse dare una mano lo ringrazio da subito.
Allego file con quanto fatto sinora.
office 2019
Allegati:
You must be logged in to view attached files.ciao,
non fai il salto pagina , ho aggiunto l'istruzione
driver.FindElementByCss("body > div.skin-wrap > div.content_flex_wrapper > section.markets.container-fluid > div > div:nth-child(3) > div > nav > ul > li:nth-child(7)").Click
Si potrebbe anche acorciare, ora non ho modo di testarla
driver.FindElementByCss("section.markets nav ul li:nth-child(7)").Click
Option Explicit Sub scarica_dati_finzanza() Dim th As Object Dim C As Integer, R As Integer, td As Object, tr As Object, NRow As Long, uRow As Integer Dim driver As New Selenium.ChromeDriver Dim itable As Selenium.WebElements Dim itables As Selenium.WebElements Dim i As Integer, J As Integer, n As Integer Dim Pagina As Selenium.WebElement, pg As Selenium.WebElement Dim intest Dim url As String Dim Btn1 As WebElement Cells.Clear With driver .Start "Chrome", "" .Get "https://www.milanofinanza.it/quotazioni/ricerca/listino-completo-2ae?refresh_cens" '.FindElementByClass("cl-consent__btn").Click Application.Wait (Now + TimeValue("00:00:02")) .FindElementByXPath("//a[@data-role='b_agree']").Click Application.Wait (Now + TimeValue("00:00:04")) R = 2: C = 1 intest = Array("Nome", "Ultimo prezzo", "Var %", "Ora ult. prezzo", "Volume progr.", _ "Migliore denaro", "Migliore lettera", "Prezzo di rifer.", "Apertura", "Codice ISIN", "MF Risk") Range("A1:K1") = intest For J = 1 To 72 ' pagine totali Set Pagina = driver.FindElementByTag("table") Set pg = driver.FindElementByCss("body > div.skin-wrap > div.content_flex_wrapper > section.markets.container-fluid > div > div:nth-child(3) > div > nav > ul > li:nth-child(7)") For Each th In Pagina.FindElementsByTag("tr") R = R + 1: C = 1 For Each td In th.FindElementsByTag("td") Cells(R, C).Value = td.Text If C = 1 Then url = td.FindElementByTag("a").Attribute("href") ActiveSheet.Hyperlinks.Add _ Anchor:=Cells(R, C), _ Address:=url, _ TextToDisplay:=Cells(R, C).Value End If C = C + 1 Next Next .Wait 2000 R = Cells(Rows.Count, 1).End(xlUp).Row - 1 driver.FindElementByCss("body > div.skin-wrap > div.content_flex_wrapper > section.markets.container-fluid > div > div:nth-child(3) > div > nav > ul > li:nth-child(7)").Click Next End With driver.Close driver.Quit MsgBox "Finito" End SubCiao a tutti
Ultimamente sarà cambiato qualcosa? Con SeleniumBasic-2.0.9.0 si sostituiva chromedriver.exe con la versione idonea.
Oggi installo Chrome ---> Versione 143.0.7499.170 (Build ufficiale) (a 64 bit)
Ma non riesco trovare la versione giusta in -->https://chromedriver.storage.googleapis.com/index.htmlhttps://www.nuget.org/packages/selenium.webdriver.chromedriver/
Qui ho trovato un riferimento alla versione versione 143.0.7499.16900, ma non so come procedere.
Grazie milleCiao Raffaele, io vado qui :
https://googlechromelabs.github.io/chrome-for-testing/#stable
seleziono e scarico la chromedriver a 32 bit . Ciao
Ciao @lukereds,
purtroppo, e con entrambe, ottengo errore : errore di runtime 0
Selenium error element click intercepted is not clickable at point ...
si ogni tanto capita, metti un wait di 3 o 4 secondi (anzi: 8 o 10) dopo l'istruzione sopra
Però 72 pagine sono un'enormità si pianta ad istruzioni diverse "random" senza motivo apparente
vedo ora che il sito è organizzato a tabelle, si può usare l'istruzione asTable che velocizzza molto l'esecuzione (ma 72 pag sono sempre tante). Nel file allegato sono state caricate 70 pagine. non sono 72. Se ongi tanto si pianta basta farlo ripartire, aveva bisogno di un wait
A fine sub vanno aggiunte le istruzioni per cancellare i titoli duplicati (a te l'onere, non è difficile)
Sub scarica_dati_finanza() Dim th As Object Dim c As Integer, r As Integer, td As Object, tr As Object, NRow As Long, uRow As Integer Dim driver As New Selenium.ChromeDriver Dim itable As Selenium.WebElements Dim itables As Selenium.WebElements Dim i As Integer, J As Integer, n As Integer Dim Pagina As Selenium.WebElement, pg As Selenium.WebElement Dim intest, element As Selenium.WebElement Dim url As String Dim Btn1 As WebElement Cells.Clear r = 2 With driver .Start "Chrome", "" .Get "https://www.milanofinanza.it/quotazioni/ricerca/listino-completo-2ae?refresh_cens" '.FindElementByClass("cl-consent__btn").Click Application.Wait (Now + TimeValue("00:00:02")) .FindElementByXPath("//a[@data-role='b_agree']").Click Application.Wait (Now + TimeValue("00:00:04")) r = 2: c = 1 intest = Array("Nome", "Ultimo prezzo", "Var %", "Ora ult. prezzo", "Volume progr.", _ "Migliore denaro", "Migliore lettera", "Prezzo di rifer.", "Apertura", "Codice ISIN", "MF Risk") Range("A1:K1") = intest For J = 1 To 72 ' pagine totali Set Pagina = driver.FindElementByTag("table") Pagina.AsTable.ToExcel Cells(r, 1) .Wait 3000 r = Cells(Rows.Count, 1).End(xlUp).Row + 2 driver.FindElementByCss("body > div.skin-wrap > div.content_flex_wrapper > section.markets.container-fluid > div > div:nth-child(3) > div > nav > ul > li:nth-child(7)").Click .Wait 8000 Next End With driver.Close driver.Quit MsgBox "Finito" End SubAllegati:
You must be logged in to view attached files.@lukereds , grazie tutto Ok.
Magari , quando hai tempo se mi spieghi come sei arrivato a questo CSS
driver.FindElementByCss("body > div.skin-wrap > div.content_flex_wrapper > section.markets.container-fluid > div > div:nth-child(3) > div > nav > ul > li:nth-child(7)").Click
lo hai costruito tu ? oppure quale sezione dell'html hai selezionato per avere il CSS ?
Quando sei sull'html del sito, tasto dx sulla freccia (pagina successiva, ">") poi "copy" - "copy selector" ed ottieni la stringa sopra (che si potrebbe accorciare, ma è un altro discorso)
Allegati:
You must be logged in to view attached files.@lukereds, hai notato che il numero finale varia in base a quale pagina stai visualizzando?
Secondo te perché non funziona con >>>............li:nth-child(" & J + 1 & ")").Click
1)body > div.skin-wrap > div.content_flex_wrapper > section.markets.container-fluid > div > div:nth-child(3) > div > nav > ul > li:nth-child(2) > a
3)body > div.skin-wrap > div.content_flex_wrapper > section.markets.container-fluid > div > div:nth-child(3) > div > nav > ul > li:nth-child(4) > a
si è una cosa comune se ci sono più pagine, si potrebbe anche, con un ciclo, fare un GET per ogni pagina. Ma i tempi di esecuzione rimarrebbero gli stessi
Ciao, un altro problema è che dato il numero di pagine elevato a un certo punto il sito viene chiuso o interdetto lo scarico dati , può essere secondo voi? Perchè chiedo questo? ovvero mi sono accorto che nel download non arrivo mai ai titoli W o Z .
nel file che avevo allegato ci sono tutte le azioni
Allegati:
You must be logged in to view attached files.funziona anche il metodo XML, sul mio pc carica le 72 pagine in meno di 30 secondi
Controlla di aver abilitato le librerie nell'immagine
Sub Azioni() Dim c, r, i Dim XMLreq As New MSXML2.XMLHTTP60 Dim doc As New MSHTML.HTMLDocument Dim elems As MSHTML.IHTMLElementCollection Dim tr As MSHTML.IHTMLElement, td As MSHTML.IHTMLElement r = 2 For i = 1 To 72 XMLreq.Open "GET", "https://www.milanofinanza.it/quotazioni/ricerca/listino-completo-2ae?campoord=&ord=&alias=&selettorecod=&pag=" & i, False XMLreq.send doc.body.innerHTML = XMLreq.responseText Set elems = doc.getElementsByTagName("tbody") For Each tr In elems(0).getElementsByTagName("tr") For Each td In tr.getElementsByTagName("td") c = c + 1 Cells(r, c) = td.innerText Next td r = r + 1: c = 0 Next tr Next i End SubAllegati:
You must be logged in to view attached files.@lukereds
Complimenti vivissimiRiguardo il codice precedente, adesso mi funziona il >>> . . . :nth-child(" & J + 1 & ")").Click
Ultima richiesta mi sai dire come posso catturare in un Msgbox la scritta "Trovati 1437 risultati: pagina 1 di 72" in prima pagina?vuoi il messaggio in una msgbox o in una cella? se in una msgbox (ho aggiunto un'istruzione che cancella i dati preesistenti)
`Sub Azioni() Dim c, r, i, np Dim XMLreq As New MSXML2.XMLHTTP60 Dim doc As New MSHTML.HTMLDocument Dim elems As MSHTML.IHTMLElementCollection Dim tr As MSHTML.IHTMLElement, td As MSHTML.IHTMLElement Range("A2:K2000").ClearContents r = 2 For i = 1 To 72 np = np + 1 XMLreq.Open "GET", "https://www.milanofinanza.it/quotazioni/ricerca/listino-completo-2ae?campoord=&ord=&alias=&selettorecod=&pag=" & i, False XMLreq.send doc.body.innerHTML = XMLreq.responseText Set elems = doc.getElementsByTagName("tbody") For Each tr In elems(0).getElementsByTagName("tr") For Each td In tr.getElementsByTagName("td") c = c + 1 Cells(r, c) = td.innerText Next td r = r + 1: c = 0 Next tr Next i MsgBox ("Numero pagine " & np & vbCrLf & "Numero titoli " & r - 2) End Sub`Non intendevo questa soluzione, chiedevo riguardo il codice per Selenium. Non importa pensavo d'estrapolare dalla 1°pagina la stringa "Trovati 1437 risultati: pagina 1 di 72" in modo tale da estrarci una variabile nN=72 per usare in seguito col ciclo FOR J = 1 to nN (presumendo che il 72 con sia un dato certo in futuro)
ti conviene usare selenium? sono 25 - 30 minuti... contro 30 secondi...
Ad ogni modo nella prima pagina non vedo informazioni sul numero titoli e numero pagine
Il problema che non conosco il Tuo metodo (sembra IEXPLORE che dovrebbe essere out), grazie se mi dai un Link dove mi spiega il tutto.
Allegati:
You must be logged in to view attached files. -
AutoreArticoli
