Extraire des données web depuis un site qui utilise javascript [Résolu/Fermé]

Signaler
Messages postés
15
Date d'inscription
lundi 28 juillet 2014
Statut
Membre
Dernière intervention
29 juillet 2014
-
 stef -
Bonjour,
Cela fait deux jours que je cherche une solution à mon probleme sur les forums et malgré la relative fréquence à laquelle il doit se poser a des internautes je ne trouve pas de solutions dans ce cas précis :
L'exercice est simple, je veux exploiter des données d'un site web sur excel. Aujourd'hui je fais des copier-coller de centaines de pages et je voudrais automatiser. J'utilise donc la fonction données externes « a partir du web », je peux même intégrer l'import dans une macro qui va générer automatiquement les URL à importer mais problème : le site sur lequel je recupere les données utilise des commandes javascript pour afficher les données... je ne peux donc pas entrer les parametres de recherche dans l'url et excel comme IE me repond «Données non disponibles car les paramètres dans la requête http sont incorrects »
Voici le site en question :
http://alize2.finances.gouv.fr/communes/eneuro/RDep.php?type=BPS&dep=001 (base de données publique sur la comptabilité des communes - ici, celles de l'ain)
et l'url de la page que je souhaite recupérer :
http://alize2.finances.gouv.fr/communes/eneuro/detail.php
Vous remarquerez dans mes descriptions que je suis néophyte mais je me suis accroché pour chercher des solutions dans 4 directions entre lesquelles je ne sais pas choisir et que je ne sais pas mettre en oeuvre :
1 - Je charge http://alize2.finances.gouv.fr/communes/eneuro/detail.php et dans la cosole d'IE ou firefox je saisie la commande : javascript=openWithPostData('detail.php',{'ICOM':'001','DEP':'001','TYPE':'BPS','PARAM':0,'EXERCICE':'2013'})
Cela m'ouvre les données de la commune 001 (ICOM) du departement 001 (DEP) pour 2013.
1ere piste : construire une macro qui permet d'ouvrir une page web et envoyer une commande javascript via la console (ctrl+shift+k) d'IE, puis recuperer la page sur excel ??

2 - Utiliser l'importateur excel de données externes « a partir du web » et intégrer la commande javascript dans l'url (est ce que c'est possible ?)
3 - Lancer une commande javascript a partir d'excel. C'est possible en saisissant la commande dans une cellule en tant que lien hypertexte : javascript:document.open();document.write("toto");document.close()
Ducoup la commande serait un truc du style :
javascript=ouvre l'url (http://alize2.finances.gouv.fr/communes/eneuro/detail.php) ; openWithPostData('detail.php',{'ICOM':'001','DEP':'001','TYPE':'BPS','PARAM':0,'EXERCICE':'2013'}) ; copie les données().

4 - une macro qui ouvre http://alize2.finances.gouv.fr/communes/eneuro/RDep.php?type=BPS&dep=001 et ouvre successivement tous les bons liens jusqu'à arriver a la feuille que je souhaite ??

Merci par avance de votre aide

7 réponses

Messages postés
12247
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
10 février 2021
2 574
On se contente donc d'un copié/collé?

Si oui, voici le code complet :

Option Explicit

'SOURCES :
    'Manipuler IE depuis VBA :
    'http://qwazerty.developpez.com/tutoriels/vba/ie-et-vba-excel/
    
    'Sendkeys & Vider_Presse_Papier : MichDenis
    'http://www.generation-nt.com/reponses/pb-avec-sendkeys-ctrl-plusa-ctrl-plusc-ctrl-plusv-entraide-3545931.html
    
'REFERENCES :
    'Pour manipuler IE, il nous faudra activer deux références :
        '« Microsoft Internet Controls »
        '« Microsoft HTML Object Library ».
    'Pour accéder aux références dans VBA, menu Outils -> Références.
    
Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function EmptyClipboard Lib "user32" () As Long
Private Declare Function CloseClipboard Lib "user32" () As Long

Dim Trouve As Boolean

Sub VaChercherSurInternet(Site As String, Ville As String, Annee As String)
Dim IE As New InternetExplorer
Dim IEDoc As HTMLDocument
Dim htmlTagCol As IHTMLElementCollection
Dim Lien As String, MsgErreur As String

Vider_Presse_Papier

'Ouvre Internet Explorer à la page référencée en B1 et B2
IE.navigate Site
IE.Visible = True

WaitIE IE

Set IEDoc = IE.document
Set htmlTagCol = IEDoc.getElementsByTagName("a")

'Boucle sur tous les liens et clic sur celui de la première lettre de la ville référencée en B3
Lien = Left(Ville, 1)
Trouve = False
Clic_Sur_Lien htmlTagCol, Lien, IE

'Traitement si la première lettre n'est pas trouvée dans les liens
If Trouve = False Then
    MsgErreur = Left(Ville, 1) & " non trouvée dans les liens du site : " & Site
    GoTo ErreurUrl
End If

Set IEDoc = IE.document
Set htmlTagCol = IEDoc.getElementsByTagName("a")
'Boucle sur tous les liens et clic sur celui de la ville référencée en B3
Lien = "*" & Ville & "*"
Trouve = False
Clic_Sur_Lien htmlTagCol, Lien, IE

'Traitement si la ville n'est pas trouvée dans les liens
If Trouve = False Then
    MsgErreur = "Ville " & Ville & " non trouvée."
    GoTo ErreurUrl
End If

Set IEDoc = IE.document
Set htmlTagCol = IEDoc.getElementsByTagName("a")
'Boucle sur tous les liens et clic sur celui de la ville référencée en B3 + "Budget principal"
Lien = "*" & Ville & "*" & "(Budget principal" & "*"
Trouve = False
Clic_Sur_Lien htmlTagCol, Lien, IE

'Traitement si budget prinicpal n'est pas trouvée dans les liens
If Trouve = False Then
    MsgErreur = "Le lien budget principal de la ville " & Ville & " n'a pas été trouvé."
    GoTo ErreurUrl
End If

Set IEDoc = IE.document
Set htmlTagCol = IEDoc.getElementsByTagName("a")
'Boucle sur tous les liens et clic sur celui de l'année référencée en B4
Lien = Annee
Trouve = False
Clic_Sur_Lien htmlTagCol, Lien, IE

'Traitement si l'année n'est pas trouvée dans les liens
If Trouve = False Then
    MsgErreur = "Le lien budget principal de la ville " & Ville & " pour l'année : " & Annee & " n'a pas été trouvé."
    GoTo ErreurUrl
End If

Set IEDoc = IE.document
Set htmlTagCol = IEDoc.getElementsByTagName("a")
'Boucle sur tous les liens et clic sur "Fiche détaillée"
Lien = "Fiche détaillée"
Trouve = False
Clic_Sur_Lien htmlTagCol, Lien, IE

'Traitement si la fiche n'est pas trouvée dans les liens
If Trouve = False Then
    MsgErreur = "La fiche détaillée du budget de la ville " & Ville & " pour l'année : " & Annee & " n'a pas été trouvé."
    GoTo ErreurUrl
End If

Application.SendKeys "^a"
Application.Wait Now + TimeValue("00:00:01")
Application.SendKeys "^c"
Application.Wait Now + TimeValue("00:00:01")
With Sheets("Feuil2")
    .Select
    .Cells.Delete 'suppression de toutes les lignes de la feuille!!!!!
    .Range("A1").Select 
    .Paste
End With

IE.Quit

Set IE = Nothing
Set IEDoc = Nothing
Set htmlTagCol = Nothing

Vider_Presse_Papier

MsgBox "Importation terminée avec succès.", vbInformation

Exit Sub

ErreurUrl:
MsgBox MsgErreur
End Sub

Function Clic_Sur_Lien(CollectionLiens As IHTMLElementCollection, Lien As String, IE As InternetExplorer)
Dim mesLiens As IHTMLElement, Attente As Long
If Sheets("Feuil1").Range("B5").Value = "" Then Sheets("Feuil1").Range("B5").Value = 2
Attente = CLng(Sheets("Feuil1").Range("B5").Value) * 1000
For Each mesLiens In CollectionLiens
    If mesLiens.innerText Like Lien Then
        mesLiens.Click
        Trouve = True
    End If
    If Trouve Then Exit For
Next
Sleep Attente
WaitIE IE
End Function

Sub WaitIE(IE As InternetExplorer)
   'On boucle tant que la page n'est pas totalement chargée
   Do Until IE.readyState = READYSTATE_COMPLETE
      DoEvents
   Loop
End Sub

Sub Vider_Presse_Papier()
OpenClipboard 0
EmptyClipboard
CloseClipboard
End Sub


Et le classeur exemple : https://www.cjoint.com/c/DGDmkDrvlzU
Cordialement,
Franck
1
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 65492 internautes nous ont dit merci ce mois-ci

Messages postés
15
Date d'inscription
lundi 28 juillet 2014
Statut
Membre
Dernière intervention
29 juillet 2014

excellent!!
c'est parfait, merci pijaku, merci la belgique!!

RESOLU!
Messages postés
12247
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
10 février 2021
2 574
Mais de rien le Parisien...
A+
Messages postés
12247
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
10 février 2021
2 574
Bonjour,

J'ai redirigé car je penses que pour réaliser ce que tu souhaites, il nous faudra un petit "programme" en VBA.

Si tu veux bien, nous pouvons débuter cela.

Tu disposes d'Internet Explorer sur le(s) pc(s) ou est censé fonctionner ton classeur Excel?

Messages postés
12247
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
10 février 2021
2 574
Ps : je penses utiliser la méthode décrite dans ton 4- :
une macro qui ouvre http://alize2.finances.gouv.fr/communes/eneuro/RDep.php?type=BPS&dep=001 et ouvre successivement tous les bons liens jusqu'à arriver a la feuille que je souhaite ??
Messages postés
15
Date d'inscription
lundi 28 juillet 2014
Statut
Membre
Dernière intervention
29 juillet 2014

oui, j'ai IE 11 et firefox.
Merci pour ta reponse rapide!!!
Messages postés
15
Date d'inscription
lundi 28 juillet 2014
Statut
Membre
Dernière intervention
29 juillet 2014

pour le chemin jusqu'a la page des données comptable c'est:

http://alize2.finances.gouv.fr/communes/eneuro/RDep.php?type=BPS&dep=001

puis la commune en question

puis le lien "budget principal"

puis l'onglet de l'année

puis le lien "fiche detaillée"

mais je pourrai peut etre extrapoler si deja tu me montres comment ouvrir un lien avec vba et importer les données :)
Messages postés
12247
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
10 février 2021
2 574
Bon.
Voici un début de réponse :
- ouvre le site
- clic sur le lien "B"

Option Explicit

Sub VaChercherSurInternet()
Dim IEDoc As HTMLDocument
Dim htmlTagCol As IHTMLElementCollection
Dim Lien As IHTMLElement

IE.navigate "http://alize2.finances.gouv.fr/communes/eneuro/RDep.php?type=BPS&dep=001"
IE.Visible = True

Do Until IE.readyState = READYSTATE_COMPLETE
DoEvents
Loop

Set IEDoc = IE.document
Set htmlTagCol = IEDoc.getElementsByTagName("a")

For Each Lien In htmlTagCol
If Lien.innerText = "B" Then Lien.Click
Next

Set IE = Nothing
Set IEDoc = Nothing
Set htmlTagCol = Nothing
End Sub

Messages postés
15
Date d'inscription
lundi 28 juillet 2014
Statut
Membre
Dernière intervention
29 juillet 2014

le debogueur me dit:

Sub VaChercherSurInternet()
Dim IEDoc As HTMLDocument

type defini par l'utilisateur non defini...
Messages postés
12247
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
10 février 2021
2 574
Oubli de ma part ...

Pour manipuler IE, il faut activer deux références : Microsoft Internet Controls et Microsoft HTML Object Library.
Pour accéder aux références dans VBA, menu Outils / Références.
>
Messages postés
12247
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
10 février 2021

Merci Pikaju, tu viens de résoudre mon problème ;)
Messages postés
15
Date d'inscription
lundi 28 juillet 2014
Statut
Membre
Dernière intervention
29 juillet 2014

lien.innerText = "B" ça recherche les liens tels qu'ils sont affichés sur la page ou ça recherche dans le lien hypertexte?

dans le premier cas je comprends donc que je dois remplacer B par le nom de la commune.

puis une fois sur cette nouvelle page je relance une boucle pour chercher "Budget principal"

puis je copie les données
Messages postés
12247
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
10 février 2021
2 574
Un fichier exemple, à la "va-vite".
Rien n'est optimisé. Pour l'instant je n'en suis qu'à l'accès à la page "budget principal"...
Messages postés
15
Date d'inscription
lundi 28 juillet 2014
Statut
Membre
Dernière intervention
29 juillet 2014

enorme!
je viens de regarder le code et je suis un peu largué mais je vais creuser.
pour l'instant je dois modifier les instructions Declare et les marquer avec PtrSafe pour que le code puisse etre utilisé sur les syteme 64bit..
Messages postés
15
Date d'inscription
lundi 28 juillet 2014
Statut
Membre
Dernière intervention
29 juillet 2014

merci beaucoup.
Messages postés
12247
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
10 février 2021
2 574
Deux choses à bien comprendre :

Set IEDoc = IE.document
Place le document Html ouvert dans une variable

Set htmlTagCol = IEDoc.getElementsByTagName("a") 
Place tous les liens du document html (IEDoc) dans une "variable" de type Collection.

Après le code n'est que boucles et traitement d'erreur...

Si :
monLien.innerText
retourne le texte affiché du lien...

Voici le fichier qui va au bout.

Fais des tests sur les traitements d'erreur en changeant les cellules B1 à B4 une par une...

Le code pour celles et ceux qui passeraient par ici :
Option Explicit


'SOURCES :
'http://qwazerty.developpez.com/tutoriels/vba/ie-et-vba-excel/

'Pour manipuler IE, il nous faudra activer deux références :
'« Microsoft Internet Controls »
'« Microsoft HTML Object Library ».
'Pour accéder aux références dans VBA, menu Outils -> Références.


Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Dim Trouve As Boolean

Sub VaChercherSurInternet(Site As String, Ville As String, Annee As String)
Dim IE As New InternetExplorer
Dim IEDoc As HTMLDocument
Dim htmlTagCol As IHTMLElementCollection
Dim Lien As String, MsgErreur As String

'Ouvre Internet Explorer à la page référencée en B1 et B2
IE.navigate Site
IE.Visible = True

WaitIE IE

Set IEDoc = IE.document
Set htmlTagCol = IEDoc.getElementsByTagName("a")

'Boucle sur tous les liens et clic sur celui de la première lettre de la ville référencée en B3
Lien = Left(Ville, 1)
Trouve = False
Clic_Sur_Lien htmlTagCol, Lien, IE

'Traitement si la première lettre n'est pas trouvée dans les liens
If Trouve = False Then
MsgErreur = Left(Ville, 1) & " non trouvée dans les liens du site : " & Site
GoTo ErreurUrl
End If

Set IEDoc = IE.document
Set htmlTagCol = IEDoc.getElementsByTagName("a")
'Boucle sur tous les liens et clic sur celui de la ville référencée en B3
Lien = "*" & Ville & "*"
Trouve = False
Clic_Sur_Lien htmlTagCol, Lien, IE

'Traitement si la ville n'est pas trouvée dans les liens
If Trouve = False Then
MsgErreur = "Ville " & Ville & " non trouvée."
GoTo ErreurUrl
End If

Set IEDoc = IE.document
Set htmlTagCol = IEDoc.getElementsByTagName("a")
'Boucle sur tous les liens et clic sur celui de la ville référencée en B3 + "Budget principal"
Lien = "*" & Ville & "*" & "(Budget principal" & "*"
Trouve = False
Clic_Sur_Lien htmlTagCol, Lien, IE

'Traitement si budget prinicpal n'est pas trouvée dans les liens
If Trouve = False Then
MsgErreur = "Le lien budget principal de la ville " & Ville & " n'a pas été trouvé."
GoTo ErreurUrl
End If

Set IEDoc = IE.document
Set htmlTagCol = IEDoc.getElementsByTagName("a")
'Boucle sur tous les liens et clic sur celui de l'année référencée en B4
Lien = Annee
Trouve = False
Clic_Sur_Lien htmlTagCol, Lien, IE

'Traitement si l'année n'est pas trouvée dans les liens
If Trouve = False Then
MsgErreur = "Le lien budget principal de la ville " & Ville & " pour l'année : " & Annee & " n'a pas été trouvé."
GoTo ErreurUrl
End If

Set IEDoc = IE.document
Set htmlTagCol = IEDoc.getElementsByTagName("a")
'Boucle sur tous les liens et clic sur "Fiche détaillée"
Lien = "Fiche détaillée"
Trouve = False
Clic_Sur_Lien htmlTagCol, Lien, IE

'Traitement si la fiche n'est pas trouvée dans les liens
If Trouve = False Then
MsgErreur = "La fiche détaillée du budget de la ville " & Ville & " pour l'année : " & Annee & " n'a pas été trouvé."
GoTo ErreurUrl
End If

Set IE = Nothing
Set IEDoc = Nothing
Set htmlTagCol = Nothing

Exit Sub

ErreurUrl:
MsgBox MsgErreur
End Sub

Function Clic_Sur_Lien(CollectionLiens As IHTMLElementCollection, Lien As String, IE As InternetExplorer)
Dim mesLiens As IHTMLElement
For Each mesLiens In CollectionLiens
If mesLiens.innerText Like Lien Then
mesLiens.Click
Trouve = True
End If
If Trouve Then Exit For
Next
Sleep 2000
WaitIE IE
End Function

Sub WaitIE(IE As InternetExplorer)
'On boucle tant que la page n'est pas totalement chargée
Do Until IE.readyState = READYSTATE_COMPLETE
DoEvents
Loop
End Sub

Avec saisie, dans la feuille active :

B1 : http://alize2.finances.gouv.fr/communes/eneuro/RDep.php?type=BPS&dep=
B2 : 001
B3 : NEUVILLE-LES-DAMES
B4 : 2011

Messages postés
15
Date d'inscription
lundi 28 juillet 2014
Statut
Membre
Dernière intervention
29 juillet 2014

whaou, ça va très vite pour moi, mais je commence a comprendre !!

Je dois préalablement essayer de reinstaller office en 64 bits pour ne plus avoir de probleme de declaration.

merci énormement pour ton temps,
je continue a apprivoiser le fichier d'exemple mais il va me falloir un peu de temps.
Messages postés
12247
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
10 février 2021
2 574
Je ne connais pas ce problème...
Peut être suffit-il de supprimer la ligne Option Explicit tout en haut du module...
Je ne sais pas...
Messages postés
15
Date d'inscription
lundi 28 juillet 2014
Statut
Membre
Dernière intervention
29 juillet 2014

Pas de soucis pour le probleme des 32 vs 64 bits c'est un pb bien documenté.

Le code marche parfaitement c'est genial.
J'essaie simplement de recuperer du coup la derniere page affichée.
J'ai ajouté cette ligne:

Sheets("feuil2").Range("a1") = IEDoc.documentElement.innerText

mais je me retrouve avec toutes les données dans une seule cellule alors que je voudrais un tableau comme sur le site... any idea pour finaliser l'opération?

Set IEDoc = IE.document
Set htmlTagCol = IEDoc.getElementsByTagName("a")
'Boucle sur tous les liens et clic sur "Fiche détaillée"
Lien = "Fiche détaillée"
Trouve = False
Clic_Sur_Lien htmlTagCol, Lien, IE

Sheets("feuil2").Range("a1") = IEDoc.documentElement.innerText
Messages postés
15
Date d'inscription
lundi 28 juillet 2014
Statut
Membre
Dernière intervention
29 juillet 2014

oui, j'essaie de trouver une autre solution mais c'est moi qui ne suis pas efficace :)

dans tout ce que j'ai lu ce matin voici quelque chose qui semble marcher et que j'essaie d'integrer dans le code ...

With Page.Document
Application.SendKeys "^a"
Application.Wait Now + TimeValue("00:00:1")
Application.SendKeys "^c"
End With
Page.Quit
Workbooks("Code bare.xls").Activate
Range("a1").Select
ActiveSheet.PasteSpecial Format:="Texte", Link:=False, DisplayAsIcon:= _
False

extrait de:

https://forums.commentcamarche.net/forum/affich-20262304-vba-copier-le-contenu-d-une-page-web-php
Messages postés
15
Date d'inscription
lundi 28 juillet 2014
Statut
Membre
Dernière intervention
29 juillet 2014

Yesssss!!! avec ca j'arrive a avoir un copier collé ligne à ligne!!!! on s'approche.

Reste plus qu'a avoir les colonnes :) je pense que ca se passe dans l'instruction du collage special..?

Set IEDoc = IE.document
Set htmlTagCol = IEDoc.getElementsByTagName("a")
'Boucle sur tous les liens et clic sur "Fiche détaillée"
Lien = "Fiche détaillée"
Trouve = False
Clic_Sur_Lien htmlTagCol, Lien, IE

With IEDoc

Application.SendKeys "^a"
Application.Wait Now + TimeValue("00:00:1")
Application.SendKeys "^c"
End With

Sheets("feuil2").Select

Range("a1").Select
ActiveSheet.PasteSpecial Format:="Texte", link:=False, DisplayAsIcon:= _
False
Messages postés
15
Date d'inscription
lundi 28 juillet 2014
Statut
Membre
Dernière intervention
29 juillet 2014

je me suis souvenu que qd je le faisais a la mano, un simple paste suffisait

With IEDoc

Application.SendKeys "^a"
Application.Wait Now + TimeValue("00:00:1")
Application.SendKeys "^c"
End With

Sheets("feuil2").Select

Range("a1").Select
ActiveSheet.Paste


Bingo!!!!!!!!!!
merci enormement pijaku.
je finalise qq traitement du tableau ainsi obtenu pour supprimer des espaces et des carateres bizarres qui empechent de ce servir des données comme des nombre (c'est a dire ce caractere entre guillemets qui n'est pas un espace : " ")

puis je poste le code definitif et je le marque en resolu!!!!!!
Messages postés
12247
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
10 février 2021
2 574
ça je l'avais également...
Mais bon le résultat n'est pas satisfaisant.
Essaie déjà avec .Paste plutôt que PasteSpecial, ce sera mieux.
ActiveSheet.Paste
Mais pas encore optimal.

J'attends toutefois ton retour...
Messages postés
15
Date d'inscription
lundi 28 juillet 2014
Statut
Membre
Dernière intervention
29 juillet 2014

Oui, c'est bien ça activesheet.paste, modulo 2 ou 3 traitements des données ça me donne quelquechose d'exploitable. Tout du moins, aussi exploitable que qd je faisais toute cette manip a la main, feuille par feuille.

Qd je disais que c'etait domage de terminer par un copier coller, je parlais d'un copier coller manuel a partir de la fiche detaillée affichée par la macro.

En relisant ton post, "Bon, j'explore d'autres solutions que le copié/collé."... je comprends le copié/collé que tu envisageais etait deja un copier/coller inclu ds la macro :) pour moi c'etait pas une etape evidente.

Au moins j'aurais eu l'impression de trouver quelque chose dans ce code :)))))
merci encore beaucoup pour le temps que tu as pris et pour celui que j'economise