Utilizzare le RegExp e IE per esplorare il Web Inviato da Administrator venerdì 24 aprile 2009 Il Blog di Excelvba Ecco l'ennesimo utilizzo delle espressioni regolari... Le routine presenti in questo articolo consentono di recuperare direttamente da internet informazioni relative ad anagrafiche di Aziende o Privati attraverso l'esplorazione di PagineGialle e PagineBianche. Si raccomanda prima dell'utilizzo di questo codice di leggere attentamente le Note Legali e le Informative sulla Privacy presenti sui siti di PagineGialle e PagineBianche raggiungibili a questi link: http://www.paginegialle.it/pg/extra/copyright/tutelacopyright.html http://www.paginegialle.it/pg/extra/privacy.html http://www.paginebianche.it/execute.cgi?&font=default&ts=113 http://www.paginebianche.it/execute.cgi?&font=default&ts=112 Tutto il codice va incollato in un modulo standard, in fondo troverete la routine test. Buon lavoro saluti r Option Explicit 'IMPORTANTE! 'Prima di procedere leggere le note legali 'e l'informativa sulla privacy nel sito 'http://www.paginegialle.it 'i link: 'http://www.paginegialle.it/pg/extra/copyright/tutelacopyright.html 'http://www.paginegialle.it/pg/extra/privacy.html 'IMPORTANTE! 'Prima di procedere leggere le note legali 'e l'informativa sulla privacy nel sito 'http://www.paginebianche.it/index.html 'i link: 'http://www.paginebianche.it/execute.cgi?&font=default&ts=113 'http://www.paginebianche.it/execute.cgi?&font=default&ts=112
Private Declare Sub Sleep Lib "kernel32" (ByVal dwmilliseconds As Long) 'funzione api di pausa Const New_Sh As String = "Res_" 'nuovo foglio base nome Const READYSTATE_COMPLETE As Long = 4 Sub Leggi_pagina_IE_categorie( _ Dalla_Lettera As String, _ Alla_Lettera As String) 'recupera le categorie scrivendole 'in un nuovo foglio Categorie Dim myurl As String Dim testo As String Dim i As Long Dim Rng As Excel.Range Dim myie As Object Dim Cs As Long, Ts As Long If Len(Dalla_Lettera & Alla_Lettera) = 2 Then  Cs = Asc(LCase(Dalla_Lettera))  Ts = Asc(LCase(Alla_Lettera))  If Cs > 96 And Cs < 123 And Ts > 96 _   And Ts < 123 And Ts >= Cs Then  Else   Exit Sub  End If End If Set myie = CreateObject("InternetExplorer.Application") If WsExist(ThisWorkbook, "Categorie") Then  Set Rng = ThisWorkbook.Worksheets("Categorie").Cells
 Rng.Clear  Set Rng = ThisWorkbook.Worksheets("Categorie").Range("A1") Else  Set Rng = ThisWorkbook.Worksheets.Add.Range("A1")  Rng.Parent.Name = "Categorie" End If myurl = "http://www.paginegialle.it/cat/elenco_alfabetico_" 'volendo non à necessario rendere visibile IE 'in questo caso commentare la prossima riga myie.visible = True On Error GoTo esci For i = 97 To 122 myie.navigate myurl & Chr(i) & ".html" Do While myie.busy Or myie.readystate <> READYSTATE_COMPLETE  DoEvents Loop testo = myie.document.body.innerhtml Elenco_Categorie testo, Rng Next esci: If TypeName(myIE) = "IWebBrowser2" Then  myie.quit ElseIf TypeName(myIE) = "Object" Then  Set myie = Nothing End If End Sub Sub Leggi_pagina_IE_2( _
Categoria As String, _ da_cap As Long, _ a_cap As Long) 'recupera gli indirizzi dal 'sito paginegialle.it Dim myurl As String Dim testo As String Dim L1 As Long Dim L3 As Long, L4 As Long Dim Rng As Excel.Range Dim v Dim myie As Object Set myie = CreateObject("InternetExplorer.Application") On Error GoTo esci v = Array( _  "Società ", _  "CAP", _  "Città ", _  "Provincia", _  "Indirizzo", _  "Civico", _  "Telefono", _  "Fax")  Set Rng = Nuovo_Range(ThisWorkbook, New_Sh) For L1 = 0 To UBound(v)  Rng.Offset(0, L1) = v(l1) Next myurl = "http://www.paginegialle.it/pgol/4-" & _
  Categoria & "/3-"   'volendo non à necessario rendere visibile IE 'in questo caso commentare la prossima riga myie.visible = True For L3 = da_cap To a_cap  If L3 Mod 10 <> 0 Then   'la prima pagina   myie.navigate _ myurl & _ L3 & _ "/p-" & _ 1 & _ "?mr=30"   Do While myie.busy Or _ myie.readystate <> READYSTATE_COMPLETE DoEvents Sleep 500   Loop     Sleep 250     testo = myie.document.body.innerhtml   Estrai testo, Rng     L4 = contapagine(testo)   'le pagine successive   For L1 = 2 To L4 myie.navigate myurl & L3 & "/p-" & L1 & "?mr=30" Do While myie.busy Or myie.readystate <> READYSTATE_COMPLETE
 DoEvents  Sleep 500 Loop Sleep 250 testo = myie.document.body.innerhtml Estrai testo, Rng   Next  End If Next L3 esci: If TypeName(myIE) = "IWebBrowser2" Then  myie.quit ElseIf TypeName(myIE) = "Object" Then  Set myie = Nothing End If End Sub Sub Leggi_bianche_IE( _ Cognome As String, _ Nome As String, _ Optional CAP As String, _ Optional vicino_a_cap As String) 'Parametro CAP à una indicazione 'di localitã volendo à possibile 'passare anche una cittã 'Idem per vicino_a_cap 'volendo effettuare una ricerca 'compilando vicino a (vicino_a_cap) 'à necessario passare anche 'il parametro CAP
Dim myie As Object Dim myurl As String Dim testo As String Dim L1 As Long Dim L3 As Long, L4 As Long Dim Rng As Excel.Range Dim v Set myie = CreateObject("InternetExplorer.Application") If Len(CAP) = 0 And Len(vicino_a_CAP) Then  Err.Raise 1001,, "Passare anche un parametro CAP!" End If Const Url = "http://www.paginebianche.it/" & _  "execute.cgi?ver=default&font=defau" & _  "lt&btt=1&ts=101&cb=8&l=it&mr=10&rk" & _  "=&om=&qs="  myurl = Url & _   Cognome & "&qsn=" & _   Nome & "&dv=" & _   CStr(CAP) & "&ind=" & _   CStr(vicino_a_CAP)   v = Array( _  "Cognome_Nome", _  "CAP", _  "Città ", _  "Provincia", _  "Civico_Indirizzo", _  "Telefono") Â
Set Rng = Nuovo_Range(ThisWorkbook, New_Sh) For L1 = 0 To UBound(v)  Rng.Offset(0, L1) = v(l1) Next 'volendo non à necessario rendere visibile IE 'in questo caso commentare la prossima riga myie.visible = True On Error GoTo esci 'la prima pagina myie.navigate myurl Do While myie.busy Or _  myie.readystate <> READYSTATE_COMPLETE  DoEvents  Sleep 500 Loop Sleep 250 testo = myie.document.body.innerhtml Estrai_tel testo, Rng L4 = contapagine_b(testo) 'eventuali altre pagine For L1 = 1 To L4-1  myie.navigate myurl & "&btt=1&mr=10&om=0&be=" & L1 * 10  Do While myie.busy Or myie.readystate <> READYSTATE_COMPLETE   DoEvents   Sleep 500
 Loop  Sleep 250  testo = myie.document.body.innerhtml  Estrai_tel testo, Rng Next esci: If TypeName(myIE) = "IWebBrowser2" Then  myie.quit ElseIf TypeName(myIE) = "Object" Then  Set myie = Nothing End If End Sub Sub Estrai(testoHtml As String, Rng As Excel.Range) Dim s As String, s1 As String Dim v Dim l As Long Dim RE As Object Dim RE2 As Object Set RE = CreateObject("vbscript.regexp") Set RE2 = CreateObject("vbscript.regexp") l = UltimaRiga(Rng.Parent) RE.Global = True Debug.Print Rng.Address s = "(<div <DIV class=client" & _ "-identifying-pg>\r?\n?)" s = s & "(<H3 class=""org orange"">" & _  "<A title="" <H3 class=org>)" s = s & "([^<-]+)" 'societã 3 s = s & "(<SPAN class=postal-code>)" s = s & "(\d{1,5})" 'cap 6
s = s & "(<SPAN class=locality>)" s = s & "([^<]+)" 'cittã 9 s = s & "(<SPAN class=region>)" s = s & "([^<]+)" 'provincia 12 s = s & "(class=street-address>)" s = s & "([^<]+)" 'indirizzo 15 s = s & "(<SPAN class=type>tel: </SPAN>)" s = s & "([0-9\s,]+)" 'telefono 18 s = s & "(</P>\r?\n?<P class=tel><span " & _  "class=type>fax:</span>[0-9\s]" & _  "+?)?" 'fax opzionale s = s & "(</P></ADDRESS>)" 'fine RE.Pattern = s If RE.test(testoHtml) Then For Each v In RE.Execute(testoHtml)  'scrivo la ragione sociale  Rng.Offset(l, 0) = _   UCase(RE.Replace(v, "$3"))  'scrivo il cap  Rng.Offset(l, 1) = _   "'" & RE.Replace(v, "$6")  'scrivo la cittã  Rng.Offset(l, 2) = _   UCase(RE.Replace(v, "$9"))  'scrivo la provincia  Rng.Offset(l, 3) = _   UCase(RE.Replace(v, "$12"))  'divido l'indirizzo dal civico
 s1 = RE.Replace(v, "$15")  RE2.Pattern = "^(.+?),(.+?)$"  RE2.Global = True  'scrivo l'indirizzo  Rng.Offset(l, 4) = "'" & _   UCase(RE2.Replace(s1, "$2"))  'scrivo il civico  Rng.Offset(l, 5) = "'" & _   RE2.Replace(s1, "$1")  'scrivo il telefono  Rng.Offset(l, 6) = _   "'" & RE.Replace(v, "$18")    'controllo se c'ã il fax  s1 = RE.Replace(v, "$19")   If Len(s1) > 0 Then   RE2.Pattern = "(</SPAN>)([0-9,\s]+)"   RE2.Global = True   'scrivo il fax   Rng.Offset(l, 7) = "'" & _   RE2.Replace(RE2.Execute(s1)(0), "$2")  End If   l = l + 1  'controllo di non essere arrivato alla  'fine del foglio  If l > Cells.Rows.Count Then   Set Rng = _   Nuovo_Range(ThisWorkbook, New_Sh)  End If Next
End If End Sub Sub Estrai_tel(testoHtml As String, Rng As Excel.Range) Dim s As String, s1 As String Dim v Dim l As Long Dim RE As Object Dim RE2 As Object Set RE = CreateObject("vbscript.regexp") Set RE2 = CreateObject("vbscript.regexp") l = UltimaRiga(Rng.Parent) RE.Global = True Debug.Print Rng.Address s = "<DIV class=""client-identifying-pg fix-identifying-pb-novv"" xmlns:pb=""pb"">\s+" s = s & "(<H3 class=org>)" s = s & "([^<-]+)" 'societã s = s & "(<SPAN class=postal-code>)" s = s & "(\d{1,5})" 'cap s = s & "(<SPAN class=locality>)" s = s & "([^<]+)" 'cittã s = s & "(<SPAN class=region>)" s = s & "([^<]+)" 'provincia s = s & "(class=street-address>)" s = s & "([^<]+)" 'indirizzo s = s & "(<LI><SPAN>)" s = s & "([0-9\s,]+)" 'telefono
RE.Pattern = s If RE.test(testoHtml) Then For Each v In RE.Execute(testoHtml)  Rng.Offset(l, 0) = _   RE.Replace(v, "$2")  Rng.Offset(l, 1) = _   "'" & RE.Replace(v, "$5")  Rng.Offset(l, 2) = _   RE.Replace(v, "$8")  Rng.Offset(l, 3) = _   RE.Replace(v, "$11")  Rng.Offset(l, 4) = _   RE.Replace(v, "$14")  Rng.Offset(l, 5) = _   "'" & RE.Replace(v, "$17")   l = l + 1   If l > Cells.Rows.Count Then   Set Rng = _   Nuovo_Range(ThisWorkbook, New_Sh)  End If Next End If End Sub Sub Elenco_Categorie(testo As String, Rng As Excel.Range) Dim RE As Object Dim M, s As String Dim D As Object Dim l As Long
l = UltimaRiga(Rng.Parent) Set RE = CreateObject("VBScript.RegExp") RE.Global = True s = "/naviga/[0-9\-]+/([a-za-z_]+)\.html" RE.Pattern = s 'scrivo le categorie For Each M In RE.Execute(testo) s = M Rng.Offset(l, 0) = _ Â RE.Replace(s, "$1") l = l + 1 Next End Sub Function contapagine_b(testohtml As String) As Long Dim RE As Object, s As String Set RE = CreateObject("VBScript.RegExp") On Error Resume Next contapagine_b = 1 RE.IgnoreCase = False RE.Global = False s = "(<P class=pagination-total>pagina " & _ "<SPAN class=blue>1</span> di <SP" & _ "AN class=blue>)(\d+)" RE.Pattern = s If RE.test(testoHtml) Then contapagine_b = CLng(RE.Replace(RE.Execute(testoHtml)(0), "$2")) End If End Function
Function contapagine(testohtml As String) As Long Dim RE As Object, s As String Set RE = CreateObject("VBScript.RegExp") On Error Resume Next contapagine = 1 RE.IgnoreCase = False RE.Global = False s = "(<P class=pagination-total>pagina " & _ "<SPAN class=orange>1</span> di <SP" & _ "AN class=orange>)(\d+)" RE.Pattern = s If RE.test(testoHtml) Then contapagine = CLng(RE.Replace(RE.Execute(testoHtml)(0), "$2")) End If End Function Function UltimaRiga(Optional Sh As Worksheet, _  Optional Rng As Range) As Long 'By Norman Jones modificata restituisce 'l'ultima riga valorizzata 'restituisce 0 se il foglio à pulito 'passando Sh verrã ignorato Rng 'passando Rng verrã ignorato Sh 'non passando argomenti verrã ricercata 'l'ultima riga valorizzata del foglio 'attivo 'utilizzata come UDF à consigliabile 'passare Rng
If Sh Is Nothing Then  If Rng Is Nothing Then   Set Rng = [a1].parent.usedrange  End If Else  Set Rng = Sh.UsedRange End If On Error Resume Next UltimaRiga = Rng.Find(What:="*", _  After:=Rng.Cells(1), _  Lookat:=xlPart, _  LookIn:=xlFormulas, _  SearchOrder:=xlByRows, _  SearchDirection:=xlPrevious, _  MatchCase:=False).Row On Error GoTo 0 End Function Function Nuovo_Range( _ Wb As Excel.Workbook, _ Optional Nome_base As _ String = "Foglio") As Excel.Range 'restituisce la cella A1 di un nuovo foglio 'il nuovo foglio viene rinominato in base 'all'argomento Nome_base Dim b As Long Set Nuovo_Range = Wb.Worksheets.Add.Range("A1") Application.ScreenUpdating = False On Error Resume Next Do
Err.Clear b = b + 1 Nuovo_Range.Parent.Name = Nome_base & b Loop While Err Application.ScreenUpdating = True End Function Function WsExist(Wb As Excel.Workbook, _ WsName As String) As Boolean 'verifica se il nome di un foglio 'esiste giã nella cartella di lavoro On Error Resume Next WsExist = IsObject(Wb.Worksheets(WsName)) End Function Sub test() MsgBox "Un messaggio ti avviserã che la procedura à terminata", _ vbokonly, _ "Inizio esplorazione" Leggi_pagina_IE_categorie "a", "c" Leggi_pagina_IE_2 "alberghi", 20121, 20121 Leggi_bianche_IE "Mensa", "Roberto" MsgBox "L'esplorazione à terminata", _ vbokonly, _ "Fine esplorazione" End Sub