Code source d'une page sur le net
bonjour a tous
voila une toute petite fonction qui peut avoir bien des utilités
elle récupère le code source d'une page sur le net au format html ou format texte
voila le code pour la fonction
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
Option Explicit
Dim Destination As String 'variable pour le chemin complet du fichier de destination
Dim l_URL As String ' variable pour le lien de la page html
Dim Lapage_en_HTML 'variable pour l'object "Microsoft.XMLHTTP"( l'object XML)
Dim sourcetext As String ' varaible pour le texte de sortie au format texte
Dim texte As String 'variable pour le texte a découpé par les ""chr(13)""
Dim i As Long ' variable pour le decompte des lignes dans le texte de sortie en html ou texte
Public Function GetCodeSource(sURL, Optional au_format_text As Boolean = "false")
Set Lapage_en_HTML = CreateObject("Microsoft.XMLHTTP") 'instancie l'object
Lapage_en_HTML.Open "GET", sURL 'ouvre l'url dans l'object
Lapage_en_HTML.Send
Do: DoEvents: Loop While Lapage_en_HTML.ReadyState <> 4 'attendre que la page soit chargée
'le code source est dans """"Lapage_en_HTML.ResponseText""""
'on créé un object "htmlfile"
With CreateObject("htmlfile")
'on y ecrit le codesource complet
.Write Lapage_en_HTML.ResponseText
'Ici on garde que le texte au format texte( sans les balises)
sourcetext = .body.innerText
End With
'selon si la variable "au_format_text" est a true ou falsele texte de sortie sera en html ou texte
GetCodeSource = IIf(au_format_text, sourcetext, Lapage_en_HTML.ResponseText)
sourcetext = ""
End Function |
veuillez noter que la variable "au_format_text" dans la fonction est "OPTIONAL" c'est cette variable qui nous servira a déterminer le format de sortie lors de son appel
et voila un exemple d'utilisation :
nous allons enregistrer le code source dans un fichier texte sur le bureau
avec les balises
Code:
1 2 3 4 5 6 7 8 9 10 11 12
|
Sub test1()
l_URL = "http://www.programme-tv.net/programme/programme-tnt.html" 'la variable l_URL contient le lien de la page html que l'on veux récupérer
Destination = "C:\users\" & Application.UserName & "\Desktop\code-source-de-lapage.txt" 'la variable destination contient le chemin complet du fichier de destination
texte = GetCodeSource(l_URL) 'avec les balises(format html)
Open Destination For Output As #1 'ouverture du nouveau fichier et ecriture de chaque ligne presente dans le texte
For i = 0 To UBound(Split(texte, Chr(13)))
Print #1, Split(texte, Chr(13))(i)
Next
'fermeture du fichier après écriture
Close #1
End Sub |
ou sans les balise(format texte )
Code:
1 2 3 4 5 6 7 8 9 10 11 12
|
Sub test2()
l_URL = "http://www.programme-tv.net/programme/programme-tnt.html" 'la variable l_URL contient le lien de la page html que l'on veux récupérer
Destination = "C:\users\" & Application.UserName & "\Desktop\code-source-de-lapage.txt" 'la variable destination contient le chemin complet du fichier de destination
texte = GetCodeSource(l_URL, True) 'sans les balises(format texte)
Open Destination For Output As #1 'ouverture du nouveau fichier et ecriture de chaque ligne presente dans le texte
For i = 0 To UBound(Split(texte, Chr(13)))
Print #1, Split(texte, Chr(13))(i)
Next
'fermeture du fichier apres ecriture
Close #1
End Sub |
bien sur le lien de la page est a renseigner ici:
Code:
l_URL = "http://www.programme-tv.net/programme/programme-tnt.html"
voila elle fonctionne parfaitement bien et pour une fois le code est propre et commenté:mouarf::mouarf:
qu'en pensez vous ?
petite mise ajour (ameliorationn du code )
Bonjour
je vous propose aujourd'hui une petite mise a jour
ayant travailler sur divers demande ces derniers jour sur la récupération d'élément dans une page html pour plusieurs membres
j'ai décidé de mettre au gout du jour ma petite fonction magique
j'utilise maintenant un 3 Emme argument de type booleen pour l'attente du readystate sur l'objet
utilisé normalement avec la méthode "POST" et non pas "GET"
je garde la méthode "GET" car la méthode "POST" génère des erreurs lors du traitement du texte
la boucle do loop a donc disparu
j'ai aussi séparer la transformation en texte normal j'en ai fait une fonction séparée
j'ai ajouté aussi une nouvelle fonction "GetElementBY" qui avec 3 arguments vous récupère un tableau d'élément par balise ou par classe
a mettre en haut de module
Code:
1 2 3 4 5 6 7 8 9 10 11
| Option Explicit
'*********************************************************
'constantes pour les arguments de recherches *
' *
Public Const classe = "class=""" ' *
Public Const ID = "id=""" ' *
Public Const TR = "<tr>" ' *
Public Const TD = "<td>" ' *
' *
' Vous pouvez ajouter des constante pour les Balises ICI * *
' ******************************************************** |
voila la fonction de récupération du code source
Code:
1 2 3 4 5 6 7 8 9
|
Public Function GetCodeSource(sURL, Optional au_format_text As Boolean = "false")
Dim Lapage_en_HTML As Object
Set Lapage_en_HTML = CreateObject("Microsoft.XMLHTTP") 'instancie l'object
Lapage_en_HTML.Open "GET", sURL, False 'ouvre l'url dans l'object
Lapage_en_HTML.Send ' envoie la requette
'selon si la variable "au_format_text" est a true ou falsele texte de sortie sera en html ou texte
GetCodeSource = IIf(au_format_text, Html_to_text(Lapage_en_HTML.ResponseText), Lapage_en_HTML.ResponseText)
End Function |
voila la fonction de transformation du code source en texte normal
Code:
1 2 3 4 5 6 7 8 9 10
|
Public Function Html_to_text(codesource)
'on créé un objet html
With CreateObject("htmlfile")
'on y ecrit le codesource complet
.Write codesource
'Ici on garde que le texte au format texte( sans les balises)
Html_to_text = .body.innerText
End With
End Function |
voila les deux test avec ou sans balises
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
Sub test_avec_balise()
Dim text, l_URL As String
l_URL = "http://www.developpez.net/forums/f664/logiciels/microsoft-office/excel/macros-vba-excel/"
text = GetCodeSource(l_URL, False) ' le 3 eme argument est facultatif ,il est a false dans ce cas
MsgBox text
End Sub
Sub test_sans_balise()
Dim text, l_URL As String
l_URL = "http://www.developpez.net/forums/f664/logiciels/microsoft-office/excel/macros-vba-excel/"
text = GetCodeSource(l_URL, True)
MsgBox text
End Sub |
voila maintenant la nouvelle fonction de recherche par elements de type (classe,tr,td,id) on peut bien sur en ajouter ou le marquer en dur dans l'appel a la fonction
Code:
1 2 3 4 5 6
|
Public Function GetElementBY(lien As Variant, letype, Optional nom As String="") As Variant
Dim text
text = GetCodeSource(lien)
GetElementBY = Split(text, letype & nom)
End Function |
et voici un exemple d'appel a cette fonction
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
Sub test_le_GetElementBY()
Dim l_URL As String, elements
l_URL = "http://www.developpez.net/forums/f664/logiciels/microsoft-office/excel/macros-vba-excel/"
'exemple 1
'on recherche par la classe "threadbit new"
'elements = GetElementBY(URL de la page , type d'element , "nom de l'element ")
elements = GetElementBY(l_URL, classe, "threadbit new")
'exemple 2
'on rcherche les element pas le type de balise en l'occurrence ici les balises "<tr>"
'elements = GetElementBY(URL de la page , type d'element )
elements = GetElementBY(l_URL, TR)
MsgBox " Voici la dernière question qui a été traitée" & vbcrlf & Html_to_text(elements(1))
End Sub |
Voila ce petit module représente une alternative intéressante au niveau de l'efficacité par rapport a l'objet IE en terme d'attente et de temps de travail
qu'en pensez vous ??
petite amelioration pour le cache
Bonjour
Effectivement la méthode "GET" a tendance a aller récupérer la page dans le cache et non pas sur le net après la 1 ère fois
changer une ligne dans la fonction semble rectifier le probleme
Code:
Lapage_en_HTML.Open "GET", sURL & "?nocache= + Math.random()", False 'ouvre l'url dans l'Object
voila voila
Au plaisir
Amelioration et ajout d'option
Bonjour a tous
aujourdh'ui en recherchant dans mes archives j'ai retrouver des petites chose intéressantes
je vais donc vous montrer comment récupérer un table ou un élément particulier sans passer par le traitement du code en string mais directement en objet ici en l'occurrence (table)
en effet la fonction html_to_text restitue le ".innertext " de l'intégralité ou un fragment du code source
je vous propose alors une nouvelle fonction "html_to_outerhtml" qui est Kazi identique a l'autre sauf qu'elle garde la mise en forme du code ce qui va bien nous arranger pour récupérer une table par exemple
tout dabord le haut de module
je vous rappelle que des constantes peuvent etre facilement ajoutées
Code:
1 2 3 4 5 6 7 8 9 10 11
| '*********************************************************
'constantes pour les arguments de recherches *
' *
Public Const classe = "class=""" ' *
Public Const ID = "id=""" ' *
Public Const TR = "<tr>" ' *
Public Const TD = "<td>" ' *
Public Const TAble = "<table" ' *
' *
' Vous pouvez ajouter des constante pour les Balises ICI *
' ******************************************************** |
voila cette fonction
Code:
1 2 3 4 5 6 7 8 9 10
|
Public Function Html_to_outerhtml(codesource)
'on créé un objet html
With CreateObject("htmlfile")
'on y ecrit le codesource complet
.Write codesource
'Ici on garde que le texte au format outerhtml qui garde en memoire la mise en forme(pratique pour les tables)
Html_to_outerhtml = .body.outerhtml 'la fonction devient l'element mis en forme
End With
End Function |
comme vous pouvez le constater ca n'est que la derniere ligne qui change par rapport a l'autre
j'ai aussi ameliorer la fonction get elementBY
en effet dans certaines le balisage ainsi que la nomination par ID ,classe,name peuve etre un peu différente
donc la voici
Code:
1 2 3 4 5 6
|
Public Function GetElementBY(lien As Variant, Optional balise As String = "", Optional letype As String = "", Optional nom As String = "") As Variant
Dim code
code = GetCodeSource(lien) 'recuperation du codesource complet de la page avec l'apel a la fonction getcodesource
GetElementBY = Split(code, balise & letype & nom) 'decoupage du codesource par les arguments balise et type et nom du type
End Function |
essayons maintenant de récupérer la table sur une page financiere najaQ Quote
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
Sub test_de_recuptable()
Columns("A:F") = ""
[A2].Select
Dim l_URL As String, elements, mydata, fich, pag, code 'les variables utiles
l_URL = "http://www.nasdaq.com/symbol/f/historical" 'declaration de l'url
[A1] = l_URL
element = GetElementBY(l_URL, TAble)(3) 'recuperation de l'element
Set mydata = New DataObject 'instentiation du nouvel object
code = TAble & Html_to_outerhtml(Split(element, "</table>")(0)) & "</table>" 'reconstitution du code de l'élément
mydata.SetText code 'inscription du codesource de l'element reconstitué dans l'object
mydata.PutInClipboard 'mise en pressepapier
Sheets(3).Paste 'collage du tableau final dans le sheets
End Sub |
comme vous pouvez le constater je ne me sert plus de multi split pour récupérer chaque cell de la table mais d'un dataobject contenant le code source de la table et rien que la table par une variable appelée code
je le calque directement sur le sheet par un .paste
essayons maintenant de recupérer la derniere question qui a été posée sur le forum vba et exel
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13
| Sub test_recup_last_question_vba_sur_DVP()
[A2].Select
Dim l_URL As String, elements, mydata, fich, pag
l_URL = "http://www.developpez.net/forums/f664/logiciels/microsoft-office/excel/macros-vba-excel/"
elements = GetElementBY(l_URL, "<h3 ", classe, "threadtitle")
Set mydata = New DataObject
mydata.SetText Html_to_outerhtml(elements(2))
mydata.PutInClipboard
'le code du tableau est copié dans le presse-papiers
Set fich = ThisWorkbook
Set pag = fich.Sheets(3)
pag.Paste
End Sub |
je vous laisse les découvrir
qu'en pensez vous ?