Ciao Draleo e Elio,
prendendo spunto dall'ultima versione del file di Elio ho voluto provare a non utilizzare, come diceva appunto Elio stesso, IE ma MSXML2.ServerXMLHTTP per eseguire lo scraping.
N.B. ho utilizzato la versione "server" perché i link forniti da Draleo hanno come indirizzo http ma poi vengono reindirizzati in https. Utilizzando MSXML2.XMLHTTP l'accesso viene negato restituendo un errore.
Ho quindi inserito nel modulo due una seconda versione della routine elaborata da Elio (getSrcAttributeImgTag2) che esegue l'estrazione delle immagini tramite il codice html.
Ho anche modificato la routine InsertPicture aggiugendo due argomenti.
L'altezza e la largezza in centimetri delle immagini.
Ho quindi fatto in modo che se l'altezza è maggiore della larghezza è questa che viene impostata in base alla misura in cm dell'argomento cmHeight. In caso contrario è la larghezza ad essere impostata in base alla misura in cm dell'argomento cmWidth.
Per le misure dell'altezza e larghezza ho preso come valori quelli delle immagini create con la mia procedura dove le immagini vengono copiate con le stesse dimensioni del sito.
Volendo, magari modificando ulteriormente la routine di inserimento, si potrebbe inserire il paramentro dell'altezza originario (basta solo quel valore eventualmente) nel "db" e fare in modo che le immagini vengano impostate in base a quel valore.
Utilizzando la "navigazione" con l'oggetto MSXML2.ServerXMLHTTP, per elaborare 114 link, dal mio portatile, si impiegano circa 45".
Con la procedura originaria di Elio, e la navigazione tramite IE, si impiegano circa 160" (sempre dallo stesso computer).
Una particolarità è che l'elento src restituisce come testo il link con atenposto "about" e questo fa sì che il file non venga creato nel percorso di destinazione.
Ho quindi eseguito una sostituzione tra "about" e "https".
Altra cosa che ho notato, sul mio pc, è che excel nel titolo della finestra avvisa che il file "non risponde" e anche il conteggio nella barra di stato si blocca non mostrando più i numeri successivi.
Però alla fine la procedura viene portata a termine regolarmente.
Ho quindi modificato il testo della barra di stato in un più generico:
"Elaborazioni in corso. Attendere prego ...".
Ma magari è solo un problema del mio pc.
Se volete verificare questo è il file nella versione "B":
https://www.dropbox.com/s/c031ew3y1s855y2/test%20Web%20Scraping%233B.xlsm?dl=0
Riporto il testo delle due routine modificate:
Sub getSrcAttributeImgTag2()
Const DeltaStep = 25 'numero di celle tra una immagine di una Url e l'altra
Const sPathFrancobolli As String = "D:\Test\Francobolli\"
Const sPathFiligrane As String = "D:\Test\Filigrane\"
Const ImgCmHeight As Double = 7.96
Const ImgCmWidth As Double = 7.98
Dim iTimer As Long
Dim fTimer As Long
Dim result As Long
Dim objHTTP As Object
Dim htmlDoc As Object
Dim ElementCol As Object
Dim Link As Object
Dim sPath As String
Dim cTime As Date
Dim Wb As Workbook
Dim wsLink As Worksheet
Dim wsImmagini As Worksheet
Dim wsFiligrane As Worksheet
Dim wsLinkFalliti As Worksheet
Dim rngLink As Range
Dim sURL As String, sNumCat As String
Dim sURL_Response
Dim sName As String
Dim r As Range
Dim iStep As Long
Dim iLink As Long
Dim NumLink As Long
Dim sPath1 As String, sPath2 As String
Dim sDrive1 As String, sDrive2 As String
iTimer = Timer
'<--- gestione percorsi salvataggio file immagini --->
sPath1 = sPathFrancobolli
If Right(sPath1, 1) <> "\" Then sPath1 = sPath1 & "\"
sPath2 = sPathFiligrane
If Right(sPath2, 1) <> "\" Then sPath2 = sPath2 & "\"
sDrive1 = Left(sPath1, 2)
sDrive2 = Left(sPath2, 2)
With CreateObject("Scripting.FileSystemObject")
If Not .DriveExists(Left(sPath1, 2)) Then Exit Sub
If Not .DriveExists(Left(sPath2, 2)) Then Exit Sub
Select Case .GetDrive(sDrive1).DriveType
Case 0, 4, 5
Exit Sub
End Select
Select Case .GetDrive(sDrive2).DriveType
Case 0, 4, 5
Exit Sub
End Select
If Not .FolderExists(sPath1) Then .CreateFolder sPath1
If Not .FolderExists(sPath2) Then .CreateFolder sPath2
End With
'</--- gestione percorsi salvataggio file immagini --->
Set Wb = ThisWorkbook
With Wb
Set wsLink = .Worksheets("Link")
Set wsImmagini = .Worksheets("Immagini")
Set wsFiligrane = .Worksheets("Filigrane")
Set wsLinkFalliti = .Worksheets("Link_Falliti")
End With
Set rngLink = wsLink.Range("A1").CurrentRegion.Columns(1)
NumLink = rngLink.Rows.count
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
End With
On Error GoTo ErrHandler
Call CancellaWsImmagini
Call CancellaLinkFalliti
Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP")
Set htmlDoc = CreateObject("htmlfile")
For Each r In rngLink.Cells
On Error GoTo ErrHandler
iLink = iLink + 1
Application.StatusBar = "Elaborazionie in corso. Attendere prego ... " '"Link " & iLink & " di " & NumLink & " in elaborazione."
'sURL = r.Hyperlinks(1).Address 'prende l'indirizzo del link _
(da usare se le celle presentano un link)
sURL = r.Value 'prende il valore nella cella _
(da usare se le celle non presentano un link _
ma il valore della cella corrisponde all'intera URL)
sNumCat = r.Offset(, 1).Value
With objHTTP
.Open "GET", sURL, False
.send
If .Status <> 200 Then GoTo Continua
Do While .readyState <> 4
DoEvents
Loop
End With
With htmlDoc
.body.innerHTML = objHTTP.responseText
sName = .getElementById("name").innerText
End With
'Set ElementCol = html.querySelectorAll("div.item_z_pic>img")'solleva un errore 462 al successivo ciclo
Set ElementCol = htmlDoc.getElementsByTagName("img")
For Each Link In ElementCol
If LCase(ExtFind2(Link.src)) = "jpg" Then
If InStr(1, Link.src, "none-stamps") > 0 Then
'Debug.Print Link.src
ElseIf InStr(1, Link.src, "-back") = 0 Then
With wsImmagini
With .Range("A1")
With .Offset(iStep)
.Value = sURL
Call AddHyperLink(.Value, .Item(1, 1))
End With
.Offset(iStep, 1) = sNumCat
.Offset(iStep + 1) = Link.alt
With .Offset(iStep, 2)
.Value = Replace(Link.src, "about", "https")
'.Value = Link.src
Call AddHyperLink(.Value, .Item(1, 1))
result = DownloadFile2(.Value, sPath1, _
SostituisciCaratteriVietatiNomiFile(sNumCat)) 'metodo ADODB Stream. NB la routine è parametrata per la sovrascrittura in caso contario verrebbe sollevato errore 3024
If result = 1 Then
.Offset(0, 1) = sPath1 & sNumCat & ".jpg"
Call AddHyperLink(.Offset(0, 1).Value, .Offset(0, 1))
With wsImmagini
.Activate
InsertPicture sPath1 & sNumCat & ".jpg", .Range("A1").Offset(iStep), _
False, False, ImgCmHeight, ImgCmWidth, sNumCat
End With
End If
End With
End With
End With
Else
With wsFiligrane
With .Range("A1")
With .Offset(iStep)
.Value = sURL
Call AddHyperLink(.Value, .Item(1, 1))
End With
.Offset(iStep, 1) = sNumCat
.Offset(iStep + 1) = Link.alt
If LCase(ExtFind2(Link.src)) = "jpg" Then
With .Offset(iStep, 2)
.Value = Replace(Link.src, "about", "https")
Call AddHyperLink(.Value, .Item(1, 1))
result = DownloadFile2(.Value, sPath2, _
SostituisciCaratteriVietatiNomiFile(sNumCat)) 'metodo ADODB Stream NB la routine è parametrata per la sovrascrittura in caso contario verrebbe sollevato errore 3024
If result = 1 Then
.Offset(0, 1) = sPath2 & sNumCat & ".jpg"
Call AddHyperLink(.Offset(0, 1).Value, .Offset(0, 1))
With wsFiligrane
.Activate
InsertPicture sPath2 & sNumCat & ".jpg", .Range("A1").Offset(iStep), _
False, False, ImgCmHeight, ImgCmWidth, sNumCat
End With
End If
End With
End If
End With
End With
End If
End If
Next Link
Continua:
iStep = iStep + DeltaStep
result = 0
On Error GoTo ErrHandler
Next r
With wsFiligrane
.Activate
.Range("A1").Select
End With
With wsImmagini
.Activate
.Range("A1").Select
End With
fTimer = Timer
MsgBox "Tempo di esecuzione per l'elaborazione di " & iLink & " link: " & fTimer - iTimer & " secondi"
ExitProc:
With Application
.StatusBar = ""
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
End With
Exit Sub
ErrHandler:
Select Case Err.Number
Case Is = -2147467259, -2147467259
On Error Resume Next
'Call LinkFalliti(wsLinkFalliti, r.Value, Err.Description)
Err.Clear
On Error GoTo 0
Resume Continua
Case Else
MsgBox "Errore n: " & Err.Number & vbCrLf & "Descrizione:" & vbCrLf & Err.Description
Resume ExitProc
End Select
End Sub
Sub InsertPicture(PictureFileName As String, _
TargetCell As Range, _
CenterH As Boolean, _
CenterV As Boolean, _
cmHeight As Double, _
cmWidth As Double, _
Optional PictureName As String)
'modificato da https://www.exceltip.com/general-topics-in-vba/insert-pictures-using-vba-in-microsoft-excel.html
'insert a picture at the topo left position of TargetCell
'the picture can be centered horizontally and/ore vertically
Dim p As Object, t As Double, l As Double, w As Double, H As Double, sExt As String
If TypeName(ActiveSheet) <> "Worksheet" Then Exit Sub
If Dir(PictureFileName) = "" Then
Debug.Print "Non trovato file con percorso: " & PictureFileName
Exit Sub
End If
'import picture
Set p = ActiveSheet.Pictures.Insert(PictureFileName)
'determine positions
With TargetCell.Offset(2, 0)
t = .Top
l = .Left
If CenterH Then
w = .Offset(0, 1).Left - .Left
l = l + w / 2 - p.Width / 2
If l < 1 Then l = 1
End If
If CenterV Then
H = .Offset(1, 0).Top - .Top
t = t + H / 2 - p.Height / 2
If t < 1 Then t = 1
End If
End With
'position and name picture
With p
If Len(PictureName) > 0 Then
.Name = PictureName
Else
.Name = PictureFileName
End If
.Top = t
.Left = l
.Select
With Windows(1).Selection.ShapeRange(1)
.LockAspectRatio = msoTrue
If .Height >= .Width Then
.Height = Application.CentimetersToPoints(cmHeight)
Else
.Width = Application.CentimetersToPoints(cmWidth)
End If
End With
End With
Set p = Nothing
End Sub