IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VBA Access Discussion :

Récupérer des liens sur une page web en récupérant le code de la page [AC-2016]


Sujet :

VBA Access

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    188
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 188
    Points : 98
    Points
    98
    Par défaut Récupérer des liens sur une page web en récupérant le code de la page
    Bonjour.

    Je poste dans Access, parce que la majorité des recherches que j’ai pu effectuer à ce sujet donnent des réponses pour Excel et je n’ai pas les compétences pour les adapter à Access (Certains éléments de code semblent ne fonctionner que sous Excel qui par ailleurs repose sur le concept de cellules).

    J’essaye de récupérer des informations sur une page web.

    Ce site web nécessite un accès avec authentification mais n’est pas en HTTPS.

    Sur la première page, il faut saisir un login et un mot de passe pour pourvoir ensuite accéder au contenu du reste du site.

    J’ai réussi à utiliser une partie du désormais célébré code du non moins célèbre Qwazerty pour me connecter.

    J’arrive aussi à pointer une page spécifique.

    L’étape suivante, c’est de récupérer une liste de liens internet d'une centaine de lignes.

    Ces liens sont tous identiques sauf les derniers caractères Mais la dénomination qui s'affiche est à chaque lien très différente.

    Cette liste se présente sous forme d'un tableau avec, en entête, des champs à compléter en vue d'une recherche avec une fonction de filtrage dynamique et les résultats se présentent sur une ou plusieurs "pages" (on reste sur la même page internet, mais le "tableau" des liens comporte plusieurs "pages" de 10 lignes chacune).

    Pour chaque ligne, il y a un paquet d'information dont je n'ai pas besoin pour l'instant (mais qui pourraient avoir leur utilité plus tard…).

    Il se trouve que toutes les données de ce tableau sont présentes dans le code source de la page (Clic droit, "Code source de la page").

    Mais ce code source occupe 105 pages Word ou 364 410 caractères, espaces compris.

    La partie qui contient ce qui m'intéresse occupe 103 pages (pour chaque ligne, les données que je vise et celles dont je n'ai pas besoin…).

    Je ne peux malheureusement pas vous communiquer l'adresse de la page mais voici le début de la partie qui m'intéresse :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <td class="collapsible_alt"><a href="LA-PARTIE-IDENTIQUE-DU-LIEN_XXX">LE-NOM-DE-LA-PAGE</a></td><td  class="collapsible_alt"><a href="PREMIERE-INFO_LIEN">PREMIERE-INFO_NOM</a></td><td  class="collapsible_alt disabled_padding_bottom"><a href="DEUXIEME-INFO_LIEN">DEUXIEME-INFO_NOM</a><br/> <div class="complement"><a href="TROISIEME-INFO_NOM">TROISIEME-INFO_NOM</a><br/> </div> <div class="complement"><a####### Etc…########
                                            <tr>
                        <td><span class="plus">+</span></td>
    Ça, c'est le début.

    Le milieu est ici tronqué.

    Le total occupe 43 lignes sous Word (ou 2680 caractères)… pour une ligne du "tableau", soit un lien.

    Ce dont j'ai besoin, c'est uniquement :

    LA-PARTIE-IDENTIQUE-DU-LIEN_XXX">LE-NOM-DE-LA-PAGE

    Et si ça pouvait se présenter sous forme d'une liste que je pourrai importer, ça ne serait pas mal…

    LA-PARTIE-IDENTIQUE-DU-LIEN_XXX">LE-NOM-DE-LA-PAGE
    LA-PARTIE-IDENTIQUE-DU-LIEN_XXX">LE-NOM-DE-LA-PAGE
    LA-PARTIE-IDENTIQUE-DU-LIEN_XXX">LE-NOM-DE-LA-PAGE
    Etc…

    Je ne suis pas contre le fait de récupérer toutes les informations pour chaque ligne de la liste bien sûr.

    Une fois sous Access, je pense que j'arriverais à faire le détail.

    Je sais que Caféine propose de récupérer le contenu d'une page, mais je n'ai pas sus mettre en route le code (créer un bouton qui exécute ce code et recopie le contenu quelque part…).

    Par ailleurs, même en suivant le tuto de Qwazerty, il y a des éléments que je n'arrive pas à trouver (Exemple, en faisant F12, j'ai bien Outils de développement, mais je n'ai jamais trouvé "Attributs").

    Il me manque l'accès à certaines informations pour suivre et mettre en œuvre le tuto…

    Cela ne me dérange pas d'exporter tout ce contenu en code vers un fichier texte et ensuite de l'importer d'une manière ou d'une autre…

    Même si j'ai tenté un copier/coller vers un fichier texte et que quand je l'importe, je n'ai que le début de chaque ligne.

    Oui, c'est ce que je cherche à récupérer, mais c'est quand même incompréhensible et par ailleurs, quitte à avoir une explication, autant que ce soit une explication que je puisse reproduire y compris sur les cas en fin de ligne…

    En fonction du caractère séparateur que j'utilise, j'ai des informations qui disparaissent (elles ne sont pas tronquées, pas dans un autre champ, elles ne sont juste pas dans la table…) :

    Par exemple, si j'utilise > comme séparateur, j'ai deux champs, un pour "LA-PARTIE-IDENTIQUE-DU-LIEN_XXX" et l'autre pour "LE-NOM-DE-LA-PAGE", plus un champ sans intérêt.

    Bien sûr, j'ai des dizaines de lignes sans intérêt, mais bon un petit nettoyage et c'est nickel…

    Mais tout le reste des infos ligne par ligne est perdu… Tout cour.

    Dans le pire des cas, je ferais avec…

    Mais si j'utilise espace comme séparateur, j'ai 13 champs, dont aucun ne contient ce dont j'ai besoin (plus aucune trace de "LA-PARTIE-IDENTIQUE-DU-LIEN_XXX" ou "LE-NOM-DE-LA-PAGE"

    Enfin, je suis obligé d'être connecté pour récupérer la page… Donc pas possible de lancer une procédure qui pointe la page directement…

    Je conviens que des réponses existes, mais je dois vraiment avoir perdu la main, car je ne trouve que pour Excel, et je n'arrive pas à transposer.

    D'avance merci.

  2. #2
    Membre éprouvé

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Novembre 2007
    Messages
    904
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Novembre 2007
    Messages : 904
    Points : 1 229
    Points
    1 229
    Par défaut
    Bonsoir

    Est-ce que les chaînes à extraire sont toujours encadrées par des jeux de caractères identiques (un avant, un après) ?

    Titi95
    Un problème bien posé est à moitié résolu

  3. #3
    Modérateur

    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    15 331
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2005
    Messages : 15 331
    Points : 23 786
    Points
    23 786
    Par défaut
    Bonjour.

    Il va falloir faire un micro interpréteur de syntaxe.

    Les balises "lien" sont du type :

    <a href="LA-PARTIE-IDENTIQUE-DU-LIEN_XXX">LE-NOM-DE-LA-PAGE</a>

    donc la 1ère étape consiste à isoler ces textes quelque part.
    la 2nde étape va être découper la balise en morceau puis chaque morceau en sous-morceaux.

    Ici du code qui fait cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Option Compare Database
    Option Explicit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    Private Sub Test()
     
        Dim HTML As String
     
        HTML = ""
        HTML = HTML & "<td class=""collapsible_alt""><a href=""LA-PARTIE-IDENTIQUE-DU-LIEN_XXX"">LE-NOM-DE-LA-PAGE</a></td>"
        HTML = HTML & "<td  class=""collapsible_alt""><a href=""PREMIERE-INFO_LIEN"">PREMIERE-INFO_NOM</a></td>"
        HTML = HTML & "<td  class=""collapsible_alt disabled_padding_bottom""><a href=""DEUXIEME-INFO_LIEN"">DEUXIEME-INFO_NOM</a>"
        HTML = HTML & "<br/> <div class=""complement""><a href=""TROISIEME-INFO_NOM"">TROISIEME-INFO_NOM</a><br/> </div>"
        HTML = HTML & "      <div class=""complement"">"
        HTML = HTML & "<tr>"
        HTML = HTML & "<td><span class=""plus"">+</span></td>"
     
        Dim listeBaliseA_SlashA As Collection
        Dim listeMorceau As Collection
        Dim listeAttribut As Collection
     
        Set listeBaliseA_SlashA = InventorierBaliseA_SlashA(HTML)
     
        Dim b As Variant
        Dim m As Variant
        Dim a As Variant
     
        For Each b In listeBaliseA_SlashA
            Debug.Print b
     
            Set listeMorceau = DecouperMorceau(b & "")
     
            For Each m In listeMorceau
                Debug.Print , m
     
                If m & "" Like "<a *>" Then
                    Set listeAttribut = DecouperBaliseA(m & "")
     
                    For Each a In listeAttribut
                        Debug.Print , , a
                    Next a
     
                End If
     
            Next m
     
        Next b
     
        Set listeAttribut = Nothing
        Set listeMorceau = Nothing
        Set listeBaliseA_SlashA = Nothing
     
    End Sub
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    Private Sub Test_InventorierBaliseA_SlashA()
     
        Dim listeBaliseA_SlashA As Collection
     
        Dim HTML As String
     
        HTML = ""
        HTML = HTML & "<td class=""collapsible_alt""><a href=""LA-PARTIE-IDENTIQUE-DU-LIEN_XXX"">LE-NOM-DE-LA-PAGE</a></td>"
        HTML = HTML & "<td  class=""collapsible_alt""><a href=""PREMIERE-INFO_LIEN"">PREMIERE-INFO_NOM</a></td>"
        HTML = HTML & "<td  class=""collapsible_alt disabled_padding_bottom""><a href=""DEUXIEME-INFO_LIEN"">DEUXIEME-INFO_NOM</a>"
        HTML = HTML & "<br/> <div class=""complement""><a href=""TROISIEME-INFO_NOM"">TROISIEME-INFO_NOM</a><br/> </div>"
        HTML = HTML & "      <div class=""complement"">"
        HTML = HTML & "<tr>"
        HTML = HTML & "<td><span class=""plus"">+</span></td>"
        Set listeBaliseA_SlashA = InventorierBaliseA_SlashA(HTML)
     
        Dim b As Variant
     
        For Each b In listeBaliseA_SlashA
            Debug.Print b
        Next b
     
        Set listeBaliseA_SlashA = Nothing
     
    End Sub
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Public Function InventorierBaliseA_SlashA(prmHTML As String) As Collection
        Dim result As New Collection
        Dim posBaliseA As Long: posBaliseA = InStr(prmHTML, "<a ") 'Trouve la 1ère balise de début
        Dim posBaliseSlashA As Long
        Dim texteBalise As String
     
        Do While posBaliseA <> 0
            posBaliseSlashA = InStr(posBaliseA, prmHTML, "</a>") 'trouve la balise de fermeture
            texteBalise = Mid(prmHTML, posBaliseA, (posBaliseSlashA + 3) - posBaliseA + 1) 'extrait le texte d'une balise à l'autre
            Call result.Add(texteBalise) 'Mémorise le texte
            posBaliseA = InStr(posBaliseSlashA + 4, prmHTML, "<a ") 'trouve la prochaine balise de début
        Loop
     
        Set InventorierBaliseA_SlashA = result: Set result = Nothing
    End Function
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Private Sub Test_DecouperMorceau()
        Dim listeMorceau As Collection
        Set listeMorceau = DecouperMorceau("<a href=""LA-PARTIE-IDENTIQUE-DU-LIEN_XXX"">LE-NOM-DE-LA-PAGE</a>")
     
        Dim m As Variant: For Each m In listeMorceau
            Debug.Print m
        Next m
     
        Set listeMorceau = Nothing
    End Sub
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    Public Function DecouperMorceau(prmBaliseA_SlashA As String) As Collection
        Dim result As New Collection
        Dim morceau1 As String
        Dim morceau2 As String
        Dim morceau3 As String
        Dim posDelimiteur As Long
     
        posDelimiteur = InStr(prmBaliseA_SlashA, ">") 'trouve la fin de la balise d'ouvertue
        morceau1 = Mid(prmBaliseA_SlashA, 1, posDelimiteur)
     
        posDelimiteur = InStr(posDelimiteur + 1, prmBaliseA_SlashA, "<") 'trouve le début de la balise de fin
        morceau2 = Mid(prmBaliseA_SlashA, Len(morceau1) + 1, posDelimiteur - 1 - Len(morceau1))
     
        morceau3 = Mid(prmBaliseA_SlashA, posDelimiteur)
     
        Call result.Add(morceau1)
        Call result.Add(morceau2)
        Call result.Add(morceau3)
        Set DecouperMorceau = result: Set result = Nothing
    End Function
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Private Sub Test_DecouperBaliseA()
        Dim listeAttribut As Collection
        Set listeAttribut = DecouperBaliseA("<a href=""LA-PARTIE-IDENTIQUE-DU-LIEN_XXX"" A1=""TA1"" A2=""TA2"">")
     
        Dim a As Variant: For Each a In listeAttribut
            Debug.Print a
        Next a
     
        Set listeAttribut = Nothing
    End Sub
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    Public Function DecouperBaliseA(prmBaliseA As String) As Collection
        Dim result As New Collection
        Dim t As String: t = Mid(prmBaliseA, 4, Len(prmBaliseA) - 4) 'Supprime les déliteurs
     
        Dim c As String
        Dim estDansChaine As Boolean: estDansChaine = False
        Dim attribut As String: attribut = ""
     
        Dim i As Long: For i = 1 To Len(t)
            c = Mid(t, i, 1)
     
            Select Case c
                Case " "
                    'Separateur d'attribut ?
                    If Not estDansChaine Then
                            Call result.Add(attribut)
                            attribut = ""
                        Else
                            'Non finalement pas
                    End If
     
                Case """"
                    'Début ou fin de chaîne
                    estDansChaine = Not estDansChaine
     
                Case Else
                    'Ne rien faire de spécial
            End Select
     
            attribut = attribut & c
        Next i
     
        If attribut <> "" Then
            Call result.Add(attribut)
        End If
     
        Set DecouperBaliseA = result: Set result = Nothing
    End Function
    Les procédures Test permettent de valider le code loaclement avant de s'en servir ailleur.
    prm est une abréviation perso pour paramètre.

    A+
    Vous voulez une réponse rapide et efficace à vos questions téchniques ?
    Ne les posez pas en message privé mais dans le forum, vous bénéficiez ainsi de la compétence et de la disponibilité de tous les contributeurs.
    Et aussi regardez dans la FAQ Access et les Tutoriaux Access. C'est plein de bonnes choses.

  4. #4
    Membre éprouvé

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Novembre 2007
    Messages
    904
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Novembre 2007
    Messages : 904
    Points : 1 229
    Points
    1 229
    Par défaut
    Bonjour à vous deux

    SI les chaînes à extraire sont toujours encadrées par des jeux de caractères identiques (un avant, un après), voici une méthode "courte".

    Une table avec un seul enregistrement et un champ Mémo dans lequel on vient faire un copier-coller "manuel" du texte récupéré sur le site
    Une autre table dans laquelle viendront s'ajouter les chaînes extraites
    Une requête Ajout pour alimenter cette table
    Un formulaire basé sur la première table, avec une Zone de texte = Mémo de la table, deux autres Zones de texte dans lesquelles on vient mettre les valeurs des 2 balises, et un bouton qui déclenche la procédure suivante (à aménager)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Private Sub NomBouton_Click()
        Dim Debut, Fin As Integer
        Dim Extrait As String
        Debut = 1
        Fin = 1
        DoCmd.SetWarnings False
        CurrentDb.Execute ("DELETE * FROM TableRécupération)
        While InStr(Fin, Forms!f_Extraction!Recuperation, Forms!f_Extraction!Balise1) > 0
            Debut = InStr(Fin, Forms!f_Extraction!Recuperation, Forms!f_Extraction!Balise1) + Len(Forms!f_Extraction!Balise1)
            Fin = InStr(Debut, Forms!f_Extraction!Recuperation, Forms!f_Extraction!Balise2) + 1
            Extrait = Mid(Forms!f_Extraction!tw, Debut, Fin - Debut)
            DoCmd.OpenQuery "RequeteAjout"
        Wend
        DoCmd.SetWarnings True
    End Sub
    Il reste éventuellement à extraire les parties souhaités dans Extrait...

    Titi95
    Un problème bien posé est à moitié résolu

  5. #5
    Membre éprouvé

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Novembre 2007
    Messages
    904
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Novembre 2007
    Messages : 904
    Points : 1 229
    Points
    1 229
    Par défaut
    Exemple pour le découpage de Extrait à partir d'une balise intermédiaire Balise12 (valeur à entrer sur le formulaire)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        Dim Extrait1, Extrait2 As String
     
        Extrait1 = Left(Extrait, InStr(Extrait, Balise12) - 1)
        Extrait2 = Mid(Extrait, InStr(Extrait, Balise12) + Len(Balise12))
    Titi95
    Un problème bien posé est à moitié résolu

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    188
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 188
    Points : 98
    Points
    98
    Par défaut
    Bonjour à tout le monde et merci pour ces premières réponses.

    Citation Envoyé par titi95 Voir le message
    Bonsoir

    Est-ce que les chaînes à extraire sont toujours encadrées par des jeux de caractères identiques (un avant, un après) ?

    Titi95
    Oui.

    Au début de la page de code, et dans une moindre mesure à la fin, il y plusieurs lignes dont l'interet est très faible dans mon cas.

    Ensuite, on a une ligne pour chaque lien.

    Un des problèmes, c'est que pour l’équivalent d'un "champ" sur la page web, un des colonnes du tableau en fait, il peut y avoir comme contenu 1 seule info, ou plusieurs infos par cellule. les infos ont elles-même une longueur variable.

    Du coup, la longueur de la ligne de code est variable...

    Chaque ligne de lien commence toujours par <td class="collapsible_alt"><a href=" puis (sans espace) LA-PARTIE-IDENTIQUE-DU-LIEN_ puis la partie variable du lien (XXX) puis un séparateur (>), puis LE-NOM-DE-LA-PAGE puis un lot d'autres informations et de séparateurs et ça se termine par </td> (mais cette dernière chaine de caractères se retrouve aussi précédemment dans la ligne entre deux informations)

    Ensuite on passe à la ligne suivante qui contient <tr>

    Une autre ligne qui contient <td><span class="plus">+</span></td>

    Une ligne vide,

    De nouveau une ligne de lien.

    La dernière ligne de ligne n'est pas suivie des 3 lignes (<tr> <td><span class="plus">+</span></td> VIDE), mais d'une ligne </tbody> et d'une ligne </table>.

    Puis c'est le reste de la page à laquelle je n'ai pas trouvé d'utilité pour l'instant...

    Il y en tout 8 colonnes :
    Visible Non visible
    - 1 colonne de bouton pour développer le contenu de chaque ligne
    - 1 colonne des noms de page 1 nom de page 1 lien web vers l'info
    - 1 colonne première info 1 nom d'info 1 lien web vers l'info
    - 1 colonne deuxième info Rien ou 1 ou plusieurs nom(s) d'info 1 lien web pour chaque info
    - 1 colonne troisième info 1 ou plusieurs nom(s) d'info 1 lien web pour chaque info
    - 1 colonne quatrième info 1 ou plusieurs nom(s) d'info 1 lien web pour chaque info
    - 2 colonne dates 1 date par colonne rien

    La 2 premières et les 2 dernières colonnes ne contiennent toujours qu'une info (accompagnée d'un lien pour les deux premières et de rien pour les deux dernières).

    Si une colonne ne contient pas d'info, il semble que le code n'affiche pas quelque chose de particulier pour indiquer une colonne vide (en tout cas cela ne m'est pas apparu comme évident et mes premières tentatives semblent "décaler" le contenu des cellules "vers la gauche".

    Bien sûr que si je pouvais, je récupèrerais toutes les infos.

    Je serais tout à fait satisfait de récupérer une table avec un champ pour chaque colonne du tableau web.

    Je suppose qu'il serait ensuite possible de simplifier chaque champ pour ne conserver que des infos en clair et des liens web (en fait ne conserver du code que la partie affichée et la partie servant de lien…).

    Une grande partie du site propose les informations avec ce type de présentation et je pourrais donc me servir du système mis en place pour cette page en question et l'utiliser sur d'autres pages…

    Citation Envoyé par titi95 Voir le message
    [...] SI les chaînes à extraire sont toujours encadrées par des jeux de caractères identiques (un avant, un après), voici une méthode "courte". [...]
    .

    J'avais pensé à cela.

    Mais ça m’oblige à trois choses (si j'ai bien compris) :

    - Afficher manuellement le code de la page web
    - Sélectionner manuellement la partie du contenu qui m’intéresse
    - Effectuer manuellement un copier/coller dans un doucement texte dédié.

    Trois choses que je souhaite automatiser et intégrer dans une procédure et sélectionner manuellement la partie du contenu qui m’intéresse est de très loin la plus compliquée pour moi.

    Je garde cette proposition dans un coin pour l'instant. Merci.

    Citation Envoyé par marot_r Voir le message
    Il va falloir faire un micro interpréteur de syntaxe.
    Ce que je pense avoir compris, je ne l'ai pas tout compris de suite.

    En fait, on a ici 3 fonctions, et 3 autres fonctions pour pouvoir tester chaque fonction individuellement.

    Enfin, une 7ème fonction qui fait marcher les trois fonctions principales ensembles.

    Je ne voudrais pas aller plus vite que la musique, mais avec la solution que vous proposez semble impliquer que j'ai la totalité de la ligne présente dans un champ d'une table Access.

    Si tel est le cas, comme indiqué plus haut, je n'en suis pas encore là...

    J'essaye d'éviter un copier/coller manuel du code dans un fichier texte et/ou du contenu d'un fichier texte dans un champ.

    Lors de mes tentatives d'import il me manque à chaque fois des morceaux de chaque ligne (hors, si j'ai suivi, le code que vous proposez permet de tronçonner toutes les infos d'une ligne, ce qui est génial, mais ne trouvera pas d'application ici si je n'arrive pas à récupérer le contenu du code de la page dans son entier, ou au moins le contenu des lignes…

    Je vais essayer, à mon modeste niveau, de voir ce que je peux faire avec vos propositions.

    Il faut d'abord que je trouve comment recopier le code de la page dans la base et me débarrasser du début et de la fin…

    Encore Merci.

  7. #7
    Membre éprouvé

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Novembre 2007
    Messages
    904
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Novembre 2007
    Messages : 904
    Points : 1 229
    Points
    1 229
    Par défaut
    Bonsoir

    Quelques précisions concernant ma proposition.

    Effectivement, il faut faire un copier-coller du texte du site dans un champ Mémo d'une table. Peut-être "automatisable" ?
    A partir de là tu indiques les deux balises (via un formulaire) et tu lances la recherche et le stockage dans une table de toutes les chaînes trouvées entre ces deux balises.
    Donc, éventuellement tu peux relancer avec une autre paire de balises différentes si besoin.
    Et rien n'empêche de redécouper ensuite les 1ères chaînes récupérées dans la table, à partir d'autres balises, comme je te l'avais indiqué.

    Bon courage !
    Titi95
    Un problème bien posé est à moitié résolu

  8. #8
    Modérateur

    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    15 331
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2005
    Messages : 15 331
    Points : 23 786
    Points
    23 786
    Par défaut
    Ma solution supposait aussi que tu avais déjà le HTML dans un champ Access mémo.

    Actuellement tu n'as pas cela ?

    Ici du code qui fait cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Private Sub Test_LireHTML()
        Debug.Print LireHTML("www.google.ca")
    End Sub
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    Private Function LireHTML(prmURL As String)
        Dim result As String
     
        Const READYSTATE_COMPLETE   As Long = 4
     
        Dim objIE As Object
        Set objIE = CreateObject("InternetExplorer.Application")
        objIE.Navigate prmURL
     
        While objIE.busy Or objIE.readyState <> READYSTATE_COMPLETE
            DoEvents
        Wend
     
        result = objIE.Document.body.InnerHtml
     
        Set objIE = Nothing
     
        LireHTML = result
    End Function
    Et apparement en utilisant bien les propriétés et méthode de l'objet Document de IE on peut accéder à chacune des balises individuellement.
    Par contre je n'ai pas trouvé d'explication claires sur comment procéder.
    Tous les exemples que j'ai trouvés étaient orientés dans un but précis.

    A+
    Vous voulez une réponse rapide et efficace à vos questions téchniques ?
    Ne les posez pas en message privé mais dans le forum, vous bénéficiez ainsi de la compétence et de la disponibilité de tous les contributeurs.
    Et aussi regardez dans la FAQ Access et les Tutoriaux Access. C'est plein de bonnes choses.

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    188
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 188
    Points : 98
    Points
    98
    Par défaut
    Bonjour.

    J'ai tenté de vous répondre vite, car de votre côté, vous avez pris le temps de me répondre... Mais necessités de service m'en ont empêché...

    Désolé pour le retard et merci.

    Citation Envoyé par titi95 Voir le message
    [...]
    Effectivement, il faut faire un copier-coller du texte du site dans un champ Mémo d'une table. [...]
    A partir de là tu indiques les deux balises (via un formulaire) et tu lances la recherche et le stockage [...]
    [...]
    C'est un peu ce que je comptais faire au final... Dès que j'aurais trouvé comment récupérer le contenu de la page.


    Citation Envoyé par marot_r Voir le message
    Ma solution supposait aussi que tu avais déjà le HTML dans un champ Access mémo.
    Actuellement tu n'as pas cela ?
    Ici du code qui fait cela :[...]
    OK, c'est le prochain truc que j'essaye. Merci.

    Citation Envoyé par marot_r Voir le message
    Et apparement en utilisant bien les propriétés et méthode de l'objet Document de IE on peut accéder à chacune des balises individuellement.
    Par contre je n'ai pas trouvé d'explication claires sur comment procéder.
    Tous les exemples que j'ai trouvés étaient orientés dans un but précis.[...]
    C'est aussi un des problèmes que j'ai rencontré.

    Le tuto de Qwazerty propose à un moment d'ouvrir en cascade plusieurs liens sur une page (les liens sont rattachés à des boutons différents et donc il met en oeuvre une procédure pour lire les liens des boutons un à un.

    Mais je n'ai pas compris comment il fait pour repérer les liens dans la page...

    En plus, comme indiqué plus haut, il utilise certains outils du navigateur que je n'arrive pas à retrouver.

    Alors quand quelqu'un avec votre expérience indique qu'il n'a pas trouvé d'explications claires sur comment procéder, je me dit que ce ne doit quand même pas être simple.

    Je vais essayer de mettre vos propositions en oeuvre.

    Encore un grand merci.

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    188
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 188
    Points : 98
    Points
    98
    Par défaut
    Re.
    Citation Envoyé par marot_r Voir le message
    [...]

    Ici du code qui fait cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Private Sub Test_LireHTML()
        Debug.Print LireHTML("www.google.ca")
    End Sub
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Private Function LireHTML(prmURL As String)[...]
    Alors j'ai créé un formulaire avec tout ce code et un bouton qui lance Debug.Print LireHTML("www.google.ca") (en lieu et place de Private Sub Test_LireHTML()).

    Et il se passe... rien... de visible...

    Très rarement, une page web s'ouvre sur Google, ça plante en arrière plan et la ligne suivante est surlignée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    While objIE.Busy Or objIE.ReadyState <> READYSTATE_COMPLETE
    Même s'il se passe quelque chose, je n'ai pas compris comment récupérer le contenu généré par Debug.Print ou LireHTML.

    Parce que je vais évidemment en avoir besoin pour lui appliquer la suite de votre code...

    Encore merci.

  11. #11
    Modérateur

    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    15 331
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2005
    Messages : 15 331
    Points : 23 786
    Points
    23 786
    Par défaut
    Bonjour.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Debug.Print LireHTML("www.google.ca")
    Oui c'est normal que tu ne vois rien.
    Set objIE = CreateObject("InternetExplorer.Application") créé un navigateur invisible.
    Et le résultat est dans la fenêtre d'exécution immédiate.
    Elle est accessible quand tu es dans l'éditeur de code en tapant sur [Ctrl][g].

    L'erreur est plus étonnate car chez moi cela foncionne parfaitement.

    Peut-être devrait-tu, après l'instruction createObject, ajouter :

    Qui te permettrait de voir IE et peut-être d'avoir un indice sur ce qui se passe.

    LireHTML te retourne le HTML de la page dans une chaîne donc tu peux l'utiliser comme ceci avec le code que j'ai posté.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    Private Sub Test()
     
        Dim HTML As String:HTMl=LireHTML("Ici ton URL")
     
        Dim listeBaliseA_SlashA As Collection
        Dim listeMorceau As Collection
        Dim listeAttribut As Collection
     
        Set listeBaliseA_SlashA = InventorierBaliseA_SlashA(HTML)
     
        Dim b As Variant
        Dim m As Variant
        Dim a As Variant
     
        For Each b In listeBaliseA_SlashA
            Debug.Print b
     
            Set listeMorceau = DecouperMorceau(b & "")
     
            For Each m In listeMorceau
                Debug.Print , m
     
                If m & "" Like "<a *>" Then
                    Set listeAttribut = DecouperBaliseA(m & "")
     
                    For Each a In listeAttribut
                        Debug.Print , , a
                    Next a
     
                End If
     
            Next m
     
        Next b
     
        Set listeAttribut = Nothing
        Set listeMorceau = Nothing
        Set listeBaliseA_SlashA = Nothing
     
    End Sub
    Là encore le résultat est envoyé dans la fenêtre d'exécution immédiate mais on peut aussi le mettre dans une table.

    Si tu as d'autres questions n'hésite pas.

    A+
    Vous voulez une réponse rapide et efficace à vos questions téchniques ?
    Ne les posez pas en message privé mais dans le forum, vous bénéficiez ainsi de la compétence et de la disponibilité de tous les contributeurs.
    Et aussi regardez dans la FAQ Access et les Tutoriaux Access. C'est plein de bonnes choses.

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    188
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 188
    Points : 98
    Points
    98
    Par défaut
    Bonjour et merci.
    Citation Envoyé par marot_r Voir le message
    Bonjour.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Debug.Print LireHTML("www.google.ca")
    […]
    Qui te permettrait de voir IE et peut-être d'avoir un indice sur ce qui se passe.
    OK.

    Je ne sais pas encore trop pourquoi, mais maintenant, ça fonctionne.

    Le contenu est effectivement "accessible quand tu es dans l'éditeur de code en tapant sur [Ctrl][g]". Niquel.

    La suite, c'est moins simple (à mon niveau).

    Voyons si j'ai bien pigé :

    1) LireHTML est une fonction qui retourne le contenu de ma page web.
    Si j'utilise une fonction qui pointe vers LireHTML, alors la fonction travaillera sur le contenu de la page précédemment indiqué.
    Si je voulais copier ce contenu dans une table, il faudrait certainement que j'indique de copier LireHTML dans une table.

    2) InventorierBaliseA_SlashA, DecouperMorceau, DecouperBaliseA sont trois fonctions qui travaillent ensembles pour participer au résultat attendu (à savoir, recopier le contenu du tableau web dans la base Access. Pour l'instant, on est à la phase récupérer, ne garder et organiser le contenu de la page web).
    La première sub appellée Test utilise ces trois fonctions pour travailler sur un contenu HTML que je dois recopier à la main dans le code.

    3) La toute dernière procédure appelée Test, qui remplace la première, est exactement la même, sauf qu'au lieu de travailler sur le contenu recopié à la main, elle va le lire directement sur la page via LireHTML

    Du coup, pourquoi quand j'utilise les sub de test, qui permettent de tester séparément InventorierBaliseA_SlashA, DecouperMorceau, DecouperBaliseA, je rentre manuellement l'argument Set listeMorceau = DecouperMorceau("<a href=""LA-PARTIE-IDENTIQUE-DU-LIEN_XXX"">LE-NOM-DE-LA-PAGE</a>") (dans la procédure DecouperMorceau).

    Si j'ai bien compris, cet argument permet à Access de repérer le début de la première ligne d'information et ainsi commencer sa découpe, pour ne conserver que la partie intéressante du code de la page web.

    Mais quand j'utilise une des deux fonctions Test qui activent les 3 autres fonctions, je ne rentre cet argument nulle part (me semble-t-il).

    Je suppose que c'est pour cela que mon dernier essai ne m'a retourné que deux lignes du tableau…

    Je suis assez partagé deux possibilités :

    - Ne retenir que le minimum du tableau : nom de page et lien pour chaque ligne du tableau, car pour l'instant, les premiers essais ne produisent pas l'effet escompté (principalement à cause du fait que j'ai vraiment perdu la main avec Access) et ce serait peut-être plus simple de s'en satisfaire.

    - Pousser plus avant (et je me doute qu'il vous serrait bien plus simple de voir la page pour pouvoir m'aider), car la majorité des informations intéressantes du site visé sont présentées selon le même système de tableau.

    Si j'arrivais à mettre en œuvre vos conseils, je pourrais peut-être m'en servir pour toutes les pages web qui pourraient m'intéresser et récupérer des dizaines d'informations en "une seule" opération.

    Encore merci.

  13. #13
    Modérateur

    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    15 331
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2005
    Messages : 15 331
    Points : 23 786
    Points
    23 786
    Par défaut
    Bonjour.

    Oui les 3 procédures sont prévues pour être utiliser ensemble.

    Les procédures de test te pemettent de faire cela : tester et valider que les procédures fonctionnent avant de s'en servir en production.
    Il est beaucoup plus facile de tester chaque élément de ton application individuellement avec des valeurs connues en entrée (c'est pour cela que les valeurs sont en "dur" dans le code) et des valeurs connues en sortie. Cela s'appelle des tests unitaires.
    Elles ne sont pas des "vraies" parties de ton application.
    Elles peuvent aussi servir quand tu as un bug pour valider le fonctionnement pour une valeur très précise au lieu d'avoir à te taper un traitement complet de A à Bug ce qui peut être très long.
    C'est un peu comme de tester une réaction chimique en éprouvette avant de te lancer dans une production industrielle de milier de tonnes qui comportent plusieurs transformations.

    Une fois que tu as testé et validé chaque morceau de base, tu crées un morceau plus gros que tu testes et valides aussi et ainsi de suite.
    Évidement le morceau final c'est ton application. Certains implémente des tests unitaires au niveau application mais j'avoue que je me contente du niveau de ma procédure Test() en général. J'ai une procédure de test pour chaque GROS morceau et après c'est l'application.

    Donc Test() n'est là que pour démontrer comment utiliser les procédures en fournissant un environnement artificiel contrôlé.
    Actuellement ce n'est pas très exploitatble mais cela fonctionne donc on peut l'enrichir et l'adapter.
    Envoyé le résultat dans la fenêtre d'exécution immédiate est surtout utile au programmeur.
    Il te revient d'en faire une qui correspond à tes besoins.
    Par exemple, tu parles de mettre les résultats dans une table, dans ta propre procédure il faudra ajouter cela et remplacer les debug.print par des ajouts à la ou aux tables de destinations. Et tu voudras sans doute lui passer en paramètre l'URL qui t'intéresse.

    Si tu as des questions sur cela n'hésite pas.

    A+
    Vous voulez une réponse rapide et efficace à vos questions téchniques ?
    Ne les posez pas en message privé mais dans le forum, vous bénéficiez ainsi de la compétence et de la disponibilité de tous les contributeurs.
    Et aussi regardez dans la FAQ Access et les Tutoriaux Access. C'est plein de bonnes choses.

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    188
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 188
    Points : 98
    Points
    98
    Par défaut
    Bonjour.

    Merci pour votre soutient.

    Désolé marot_r, mais votre dernière explication ne me permet pas de comprendre pourquoi dans une des trois procédures de test on indique manuellement une partie du texte comme balise, mais dans la procédure de test somme des trois autres, on n'indique pas ce même texte.

    Cette dernière remarque devrait vous éclairer sur mon niveau résiduel…

    Mais tout n'est pas perdu pour autant.

    J'ai étudié la situation plus avant, notamment en m'appuyant sur vos propositions.

    J'ai 4 pages internet qui sont sensiblement présentées de la même manière, mais le code est différent.

    Le contenu de ces 4 pages, que ce soit la partie visible ou les liens qui sont attachés à ce contenu, est très intéressant et permettrait en "ne récupérant que 4 pages seulement" d'avoir pratiquement la totalité des données dont j'ai besoin.

    Plutôt que de tenter de recopier les contenus de ces pages (qui sont interminables) tout en garantissant l'anonymat des données qui s'y trouvent, je vais essayer d'indiquer ce que j'ai repéré :

    Page 1 :
    • La partie intéressante du code est précédée de <tbody> et suivie de </tbody>

    • Chaque "contenu de champ" commence par <td> ou <td quelque_chose> et finit par </td>

    • Chaque enregistrement débute par <tr>

    • Pas de balise <tr> après le dernier enregistrement

    • Au début de chaque enregistrement, il y a 3 lignes
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      <tr>
      <td><span class="plus">+</span></td>
      -------- Ligne vierge -----------
      Le <tr> de la première ligne de ce paragraphe est la balise de début d'enregistrement



    Page 2 :
    • La partie intéressante du code est précédée de <tbody> et suivie de </table> (présent une seconde fois plus loin dans le code, après celui qui m'intéresse donc, après du code qui n'est pas intéressant)

    • Chaque "contenu de champ" commence <td> et finit par </td>

    • Le premier enregistrement est précédé d'une ligne avec uniquement <tr> et un retour à la ligne

    • Chaque enregistrement se termine par <tr> et un retour à la ligne

    • Chaque enregistrement est composé de 2 lignes

    • Pas de balise <tr> après le dernier enregistrement

    • En plein milieu du code intéressant, il y a un bloc de texte inutile qui n'est pas formaté comme le reste des enregistrements et qui démarre avec <td class="notvisibleInCsv"> et finit avec </td>Ce paragraphe pourrait planter la procédure (sauf si on ajoute un système qui le supprime avant d'extraire le contenu, ou un système qui le traite comme le reste et je supprimerais la ligne correspondante dans la table finale)



    Page 3 :
    • La partie intéressante du code est précédée de <tbody> et suivie de </table> (présent une seconde fois plus loin dans le code, après celui qui m'intéresse donc, après du code qui n'est pas intéressant)

    • Chaque "contenu de champ" commence <td> et finit par </td>

    • Chaque enregistrement débute par <tr>

    • A la fin de chaque enregistrement il y a un morceau qui commence à la fin de la ligne de l'enregistrement et finit plusieurs lignes après, au début de l'enregistrement suivant :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      FIN DES DONNÉES UTILES de l'ENREGISTREMENT</a><br/></td>               <td class="notvisibleInCsv">
                          <div class="btn-group">
                              <button type="button" class="btn  btn-default dropdown-toggle" data-toggle="dropdown">
                                  Action
                                  <span class="caret"></span>
                              </button>
                              <ul class="dropdown-menu">
                                   <li><a href="pdfgen/enrolment.php?uid=6777" target="_blank">Texte Affiché</a></li></ul>
                                            </div></td></tr><tr><td>DEBUT DE L'ENREGISTREMENT SUIVANT
      Les balises <td> et </td> sont donc "perdues" au milieu de retours à la ligne…
      Et du coup, il y a aussi une balise <tr> à la fin du dernier enregistrement



    Page 4 :
    • La partie intéressante du code est précédée de <tbody> et suivie de </table> (présent une autre fois plus loin dans le code)

    • Chaque "contenu de champ" commence <td> et finit par </td>

    • Chaque enregistrement se termine par <tr> et un retour à la ligne

    • Le premier enregistrement est précédé d'une ligne avec uniquement <tr> et un retour à la ligne



    Autres :
    • Il n'y a pas toujours de balise </tbody> ou <table>

    • Des fois <td> est au début de la ligne, dès fois seul sur la ligne avant

    • Des fois on a <td class> (1 espace entre td et class), des fois <td class> (2 espaces entre td et class)…

    • Des fois il y a une balise de fermeture du même type que celle d'ouverture (<Ouverture> au début et </Ouverture> à la fin),

    • Des fois pas de balise de fermeture du même type que celle d'ouverture (peut-être que certaines balises </table> ferment tout ce qui a été ouvert avant et du coup si on en a besoin pour le dernier enregistrement il faudra la garder dans la phase de récupération du code interessant).

    • Je ne sais pas si le fait que les balises soient au début de la ligne, une ligne avant, ou en fin de la ligne précédente influe quelque chose dans le fonctionnement du code et/ou dans sa lecture par une procédure


    Idéalement une procédure du type suivant pourrait être la solution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    NomProcédure(LireHTML, BaliseDébutCode, BaliseFinCode, BaliseDébutChamp, BaliseFinChamp, BaliseDebutEnregistrement, [BaliseFinEnregistrement], [BaliseFinDernierEnregistrement])
    Les deux derniers arguments pourraient être facultatifs…

    Et le résultat serait une table (Même moche).

    Je vois à peu près comment je pourrais simplifier et alléger les enregistrements via des requêtes successives.

    J'en profite pour indiquer que je ne trouve plus le type de champ Memo sur Access 2016. On à juste le choix entre texte cours et texte long. Je suppose que texte long = memo, vu que j''ai pu y caser les 2500 caractères du code d'un enregistrement.

    Mais je ne pourrais pas y arriver tant que je n'aurais pas le contenu de ces enregistrements dans une table… et de préférence avec une seule ligne par enregistrement et une colonne par champ.

    Paradoxalement, je ne pourrais vérifier la faisabilité qu'en testant sur plusieurs dizaines de lignes (c'est généralement là qu'on voit si les moulinettes en ont oublié).

    Très clairement, je n'ai pas les compétences pour créer le code nécessaire à faire tout cela.

    Je vais essaye de voir si je peux me débrouiller en transformant LireHTLML en table pour commencer...

    Encore merci.

  15. #15
    Modérateur

    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    15 331
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2005
    Messages : 15 331
    Points : 23 786
    Points
    23 786
    Par défaut
    Bonjour.

    Désolé marot_r, mais votre dernière explication ne me permet pas de comprendre pourquoi dans une des trois procédures de test on indique manuellement une partie du texte comme balise, mais dans la procédure de test somme des trois autres, on n'indique pas ce même texte.
    Le texte en dur permet de passer manuellement une valeur à la procédure pour valider que le programme fonctionne comme attendu.

    Je vais essaye de voir si je peux me débrouiller en transformant LireHTLML en table pour commencer...
    Désolé mais je ne vois pas le gain surtout si tu veux protéger tes données.
    Passer par une chaîne de caractères qui n'est pas gardée après le traitement est bien plus confidentielle qu'une table intermédiaire.

    Sinon, il risque d'être délicat de transformer ton HTML en table car il n'est pas vraiment prévu pour cela.
    Il n'y a pas de "retour chariot" en fin de "ligne", c'est juste une suite de balises, un gros bloc de texte continue.

    Il va falloir pas mal l'analyser pour extraitre ce dont tu as besoin.
    C'est pour diminuer cet effort d'analyse que je me suis concentré seulement sur les balise <A> qui sont les balises de liens.

    Qu'a donné ma fonction de test avec l'url que tu voulais ?

    Et oui en 2016, les "mémo" sont devenus des "texte long".

    A+
    Vous voulez une réponse rapide et efficace à vos questions téchniques ?
    Ne les posez pas en message privé mais dans le forum, vous bénéficiez ainsi de la compétence et de la disponibilité de tous les contributeurs.
    Et aussi regardez dans la FAQ Access et les Tutoriaux Access. C'est plein de bonnes choses.

  16. #16
    Membre extrêmement actif Avatar de mjpmjp
    Homme Profil pro
    Retraité
    Inscrit en
    Avril 2012
    Messages
    1 133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hautes Alpes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Santé

    Informations forums :
    Inscription : Avril 2012
    Messages : 1 133
    Points : 1 441
    Points
    1 441
    Par défaut
    bonjour,
    regarde ce bout de code dans une de mes contributions...
    LinkNum = objDoc.Links.Length - 1 et objDoc.Links(n)

    tout en bas de ce lien :
    https://www.developpez.net/forums/d1.../#post10087026

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
     
            '----- Genre
            Data = ""
            LinkNum = objDoc.Links.Length - 1
            If LinkNum > 0 Then
                For n = 0 To LinkNum
                    If InStr(LCase(objDoc.Links(n)), "/genre/") > 0 Then
                        Data = Data & Split(Split(LCase(objDoc.Links(n)), "/genre/")(1), Chr(34))(0) & ";"
                    End If
                Next n
                Data = Left(Data, Len(Data) - 1)
                MsgBox Data
            End If
    @+JP
    Caractéristiques (WEB) phpMyAdmin 4-74 , PHP 5-631 , Apache 2-427 , MySQL 5-719
    Présentation NAS DS-3615xs + 20Go , DSM 6.1.6-15266 Up1 , 12 * WD 4To WD4000F9YZ (10 raid 6+ )+(2 raid 1+) , LinkSys comutateur-switch lgs528p-eu , Onduleur UPS 720W Power Boxx Lcd (4*UPS + 4*MOD)
    Mes contributions (EXCEL) Form GRAPHIQUE: Gestion des boutons , Liste Onglet dynamique...GESTION de FILM

  17. #17
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    188
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 188
    Points : 98
    Points
    98
    Par défaut
    Bonjour et merci.
    Citation Envoyé par marot_r Voir le message
    Bonjour.[…]
    Désolé mais je ne vois pas le gain surtout si tu veux protéger tes données.
    Passer par une chaîne de caractères qui n'est pas gardée après le traitement est bien plus confidentielle qu'une table intermédiaire.
    Tous les utilisateurs de "ma" base ont déjà accès à la totalité des données et des pages web traitées.

    Cette base, c'est juste pour proposer un traitement que le site web ne peut effectuer actuellement.

    Les infos ne sont pas confidentielles, ou ne sont pas attribuables.

    Mais les liens pointent vers des fiches d'information nommées.

    C'est cela que je ne peux pas diffuser sur un forum.

    Citation Envoyé par marot_r Voir le message
    Sinon, il risque d'être délicat de transformer ton HTML en table car il n'est pas vraiment prévu pour cela.
    Est-ce que ce que je vois dans la fenêtre exécution peut être transféré vers une table ?

    Évidemment dans le cas où le contenu de la fenêtre (et par la même occasion les données) étaient présentée de la bonne façon (1 ligne par enregistrement, un séparateur de champ unique).

    Citation Envoyé par marot_r Voir le message
    Il n'y a pas de "retour chariot" en fin de "ligne", c'est juste une suite de balises, un gros bloc de texte continue.
    Pourtant le code est écrit avec des retours ligne (qui, dans la plupart des cas correspondent à un changement d'enregistrement, ou de zone de texte…)

    Si le code HTML d'une page est effectivement lu comme une seule et même ligne et que ni les espaces, ni les retours à la ligne n'ont d'impact, alors c'est "pratiquement plus simple".

    Dans mon précédent message je liste les balises que j'ai repérées.

    Je ne sais par contre pas comment modifier le code que vous avez proposé, même s'il y a des éléments dont je pense avoir compris le fonctionnement.

    Peut-on imaginer quelque chose de ce type (j'ai repéré ces balises dans le code) :
    • On prend LireHTML comme document source,

    • On traite le contenu de LireHTML en commençant à partir de la balise <tbody> et ce jusqu'à la balise </table>,

    • On utilise votre fonction liste qui semble produire un retour à la ligne, en la paramétrant pour qu'elle déclenche chaque fois qu'elle trouve <tr>,

    • On fait remplacer <td> par un caractère spécial comme #,

    A cette étape, on "devrait idéalement" obtenir une grosse page de texte, avec des lignes très longues, une ligne unique par enregistrement, tous les champs séparés par #.

    • On demande la création d'une table tout en texte long avec séparation de champ chaque fois que # apparait.

    • Je prends la table et champ par champ je crée une requête qui simplifie pour ne retenir que ce que je souhaite (ça, je sais faire).
    .

    Citation Envoyé par marot_r Voir le message
    Il va falloir pas mal l'analyser pour extraire ce dont tu as besoin.
    J'ai bon espoir qu'une réorganisation des données et leur intégration dans une table (comme évoqué ci-avant) pourrait être un bon début.

    Citation Envoyé par marot_r Voir le message
    C'est pour diminuer cet effort d'analyse que je me suis concentré seulement sur les balise <A> qui sont les balises de liens.
    Et je vous en remercie beaucoup.

    Ceci-dit, maintenant que j'ai entrevu la possibilité de "mettre la main" sur autant de données en un seul "export" d'une page web plutôt que de devoir interroger des dizaines de pages, je suis plus que tenté de poursuivre dans cette voie.

    Malheureusement, je n'ai pas votre expérience en matière de rédaction de code…


    Citation Envoyé par marot_r Voir le message
    Qu'a donné ma fonction de test avec l'url que tu voulais ?
    Alors, pour être sûr que j'ai bien tout fait comme il fallait :

    J'ai recopié tel quel
    - InventorierBaliseA_SlashA
    - DecouperMorceau
    - DecouperBaliseA
    - LireHTML
    - Test (du 20/03/2018)

    Donc la seule chose que j'ai modifié dans tout ce code, c'est l'URL dans Test.


    J'ai lancé Test_LireHTML(en changeant l'URL)

    La fenêtre d'exécution n'affiche que les 31 derniers enregistrements ainsi que tout le code qui se trouve après…

    Pas une once du début du code… et des 110 premiers enregistrements.


    J'ai lancé Test.

    Le résultat est étonnant…

    Pour rappel, dans le code d'origine, certains champs contiennent plusieurs infos avec chacune un lien web associé.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    27
    28
    Ici il y a un bout du précédent enregistrement, après traitement, mais un bout seulement.
    <a href="Lien web page">nom de la page</a>
    <a href="Lien web page">
    href="Lien web page"
    nom de la page
    </a>
    <a href="1er champ – info unique_lien">nom du 1er champ – info unique</a>
    <a href="1er champ – info unique_lien">
    href="1er champ – info unique lien"
    Nom du 1er champ – info unique
    </a>
    <a href="4ème champ - 1ère info_lien"> 4ème champ - 1ère info_nom</a>
    <a href="4ème champ - 1ère info_lien ">
    href="4ème champ - 1ère info_lien "
    4ème champ - 1ère info_nom
    </a>
    <a href="4ème champ – 2ème info_lien"> 4ème champ – 2ème info_nom</a>
    <a href="4ème champ – 2ème info_lien ">
    href="4ème champ – 2ème info_lien "
    4ème champ – 2ème info_nom
     
    Etc…
     
    </a>
    <a href="4ème champ – 10ème info_lien"> 4ème champ – 10ème info_nom</a>
    <a href="4ème champ – 10ème info_lien ">
    href="4ème champ – 10ème info_lien "
    4ème champ – 10ème info_nom
    J'ai donc bien 1 ligne avec lien web et nom de page sur la même ligne (c'est ce que j'ai demandé) et tout un tas d'autres lignes avec des infos intéressantes et/ou en doublons.
    Le tout pour… seulement les deux derniers enregistrements des 31 disponibles dans le code de la page web…
    Les champs 2 et 3 étaient vides sur la page source pour ces 2 enregistrements.

    Je pense que j'ai loupé un truc…


    J'ai recommencé sub par sub :

    Test_InventorierBaliseA_SlashA (appliqué avec LireHTML sur la page web) :
    1 ligne avec le lien et nom de page (ça, c'est bon)
    Toutes les autres infos de tous les autres champs à raison d'un couple info/lien par ligne (c'est pas le top, mais c'est très lisible et ma demande d'origine est satisfaite : lien et nom de page sont séparés du reste et sur une seule ligne)
    10 enregistrement sur 31 (ça par contre, c'est pas terrible…)

    Sub Test_DecouperMorceau() retourne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <a href="LA-PARTIE-IDENTIQUE-DU-LIEN_XXX">
    LE-NOM-DE-LA-PAGE
    </a>
    Une liste avec une ligne pour chaque élément de ligne d'origine.


    Sub Test_DecouperBaliseA () retourne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    href="LA-PARTIE-IDENTIQUE-DU-LIEN_XXX"
     A1="TA1"
     A2="TA2"
    On dirait que le traitement est le même que pour Sub Test_DecouperMorceau()

    Pour ça, je sais pas trop.

    Je vois bien que votre code est capable de repérer éléments dans le code d'origine et de faire des découpes.

    Mais je n'arrive pas à piger comment indiquer les balises à prendre en compte, sinon je me lancerai dans une tentative avec les balises <tbody>, <td>, <tr> comme indiqué ci-avant...

    Sans compter que LireHTML ne prend pas tout... Mais ça non plus je ne pourrais certainement pas le réparer tout seul.

    Je suis pas très utile pour le coup..

    Encore merci.

  18. #18
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    188
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 188
    Points : 98
    Points
    98
    Par défaut
    Citation Envoyé par mjpmjp Voir le message
    bonjour,[...]
    Bonjour mjpmjp.

    Je me suis occupé de répondre à marot_r...

    Et du coup je n'ai pas vu votre réponse.

    Je vais regarder cela.

    Merci.

  19. #19
    Modérateur

    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    15 331
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2005
    Messages : 15 331
    Points : 23 786
    Points
    23 786
    Par défaut
    Bonjour.

    Mais je n'arrive pas à piger comment indiquer les balises à prendre en compte, sinon je me lancerai dans une tentative avec les balises <tbody>, <td>, <tr> comme indiqué ci-avant...
    Mon code ne tient absolument pas compte des balises autres que les balises A qui donne les liens. C'est ce que tu as demandé initialement.
    L'idée est de se concentrer seulement sur ce qui semblait t'intéresser initialement.

    Sinon, tu peux t'inspirer de InventorierBaliseA_SlashA qui part de la balise <A> et qui va jusqu'à la balise </A> et qui ramasse tout ce qu'il y a entre les deux. Une fois cela fait et comme je sais que c'est une balise A, il découpe les différents éléments de la balise.

    Ici du code qui part d'une balise passée en paramètre et qui s'arrète à la balise de fin :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    Private Sub Test()
     
        Dim HTML As String
     
        HTML = ""
        HTML = HTML & "<td class=""collapsible_alt""><a href=""LA-PARTIE-IDENTIQUE-DU-LIEN_XXX"">LE-NOM-DE-LA-PAGE</a></td>"
        HTML = HTML & "<td  class=""collapsible_alt""><a href=""PREMIERE-INFO_LIEN"">PREMIERE-INFO_NOM</a></td>"
        HTML = HTML & "<td  class=""collapsible_alt disabled_padding_bottom""><a href=""DEUXIEME-INFO_LIEN"">DEUXIEME-INFO_NOM</a>"
        HTML = HTML & "<br/> <div class=""complement""><a href=""TROISIEME-INFO_NOM"">TROISIEME-INFO_NOM</a><br/> </div>"
        HTML = HTML & "      <div class=""complement"">"
        HTML = HTML & "<tr>"
        HTML = HTML & "<td><span class=""plus"">+</span></td>"
     
        Dim listeBalise_SlashBalise As Collection
     
        Set listeBalise_SlashBalise = InventorierBalise_SlashBalise(HTML, "TD") 'obtient liste de toute les lignes de la table
     
        Dim b As Variant
     
        For Each b In listeBalise_SlashBalise
            Debug.Print b
        Next b
     
        Set listeBalise_SlashBalise = Nothing
     
    End Sub
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Public Function InventorierBalise_SlashBalise(prmHTML As String, prmBalise As String) As Collection
        Dim result As New Collection
        Dim posBalise As Long: posBalise = InStr(prmHTML, "<" & prmBalise & " ") 'Trouve la 1ère balise de début
        Dim posBaliseSlashBalise As Long
        Dim texteBalise As String
     
        Do While posBalise <> 0
            posBaliseSlashBalise = InStr(posBalise, prmHTML, "</" & prmBalise & ">")  'trouve la balise de fermeture
            texteBalise = Mid(prmHTML, posBalise, (posBaliseSlashBalise + Len(prmBalise) + 2) - posBalise + 1) 'extrait le texte d'une balise à l'autre
            Call result.Add(texteBalise) 'Mémorise le texte
            posBalise = InStr(posBaliseSlashBalise + 4, prmHTML, "<" & prmBalise & " ") 'trouve la prochaine balise de début
        Loop
     
        Set InventorierBalise_SlashBalise = result: Set result = Nothing
    End Function
    Cela suppose que tu as du code HTML bien formé c-à-d avec une balise de départ comme <A> et une balise de fin comme </a> or ce n'est pas forcément le cas. Et même avec du HTML bien formé, toutes les balises TD de mon exemple ne contiennent pas les mêmes éléments.

    Si tu n'as pas du code bien formé et régulier, extraire des infos d'une page HTML devient vraiment pénible car on ne peut pas être systématique et dire : je prend tout ce qui est entre le début et la fin et je découpe Ici et Là. Il faut identifier le début, commencer la mémorisation, puis s'arréter soit quand on attend la fin soit quand on ne peut plus lire de données. Et répéter le procéssus sur chaque balise, sachant que certaines balise HTML n'ont pas de balise de fin comme <BR> ou <br/> qui est une balise "toute seule".

    J'avoue que ton dernier post m'a un peu méllé : veux-tu toujours extrairement seulement les liens ou d'autres informations comme des éléments dans une table.

    Et ma procédure de test se contente de te "cracher" les résultats dans la fenètre de débuggage de manière à ce qu'un humain puisse le lire.
    Si tu veux les enregistrer dans un table, précise ce que tu veux garder et je t'enverai du code modifié.

    Pour un début tu n'as pas choisi un cas simple :-) c'est directement le grand bain (avec des vagues en prime).

    A+
    Vous voulez une réponse rapide et efficace à vos questions téchniques ?
    Ne les posez pas en message privé mais dans le forum, vous bénéficiez ainsi de la compétence et de la disponibilité de tous les contributeurs.
    Et aussi regardez dans la FAQ Access et les Tutoriaux Access. C'est plein de bonnes choses.

  20. #20
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    188
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 188
    Points : 98
    Points
    98
    Par défaut
    Bonjour.

    Encore merci pour cette aide.

    Désolé pour le retard à la réponse, mais je ne suis pas sur le sujet en permanence…

    Je commence par la fin.

    Citation Envoyé par marot_r Voir le message
    Bonjour.[…]
    J'avoue que ton dernier post m'a un peu méllé : veux-tu toujours extrairement seulement les liens ou d'autres informations comme des éléments dans une table.
    Je comprends et je vous prie de bien vouloir m'en excuser.

    Au départ, sur une seule des 4 pages web, il n'y avait que 2 données par enregistrement qui me semblaient intéressantes.

    Et à partir de ces 2 données, j'aurais installé un dialogue entre Access et IE pour récupérer les autres.

    Mais ce que j'ai pu expérimenter de cette possibilité de dialogue me pousse à y recourir le moins possible…

    Fort de ce que j'ai découvert en échangeant avec vous, je devine maintenant qu'il est possible de récupérer une masse d'informations sur seulement 4 pages web légèrement différentes…

    Aussi, je pense que le jeu en vaut la chandelle.

    Ce que j'arrive à faire et qui est satisfaisant

    • Dans le navigateur Web, j'affiche le code source

    • Je fais un copier du code source

    • Je le colle dans un document texte

    • Dans le document texte, j'utilise "recherche et remplace" pour remplacer toutes les balises </td> par un caractère (comme § par exemple)

    • Je supprime le début du document, avant une balise spécifique préalablement repérée, pour ne garder que le contenu du tableau web et les dernières lignes de la page de code

    • J'importe le document texte dans une table en utilisant § comme séparateur de champ et tous les champs en texte long.

    J'ai tous les enregistrements au complet séparés en 8 champs, et correctement rangés.
    Certes, il a des lignes vides que je supprime avec une requête.

    • Enfin pour simplifier le contenu des champs, voir pour en créer plusieurs et séparer les informations, j'utilise une requête avec une petite fonction de mon cru :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     Public Function EXTRAC_BALISE(PrmChamp As String, PrmBlsLft As String, PrmBlsRght As String)
    EXTRAC_BALISE = Mid(PrmChamp, InStrRev(PrmChamp, PrmBlsLft) + Len(PrmBlsLft), InStrRev(PrmChamp, PrmBlsRght) - (InStrRev(PrmChamp, PrmBlsLft) + Len(PrmBlsLft)))
    End Function
    Très très bonne idée le Prm. Je copie… Merci.
    Cette fonction permet désigner la balise au début et la balise à la fin de la chaine à récupérer.

    Elle me permet d'extraire plusieurs infos par champs récupérés plus haut et donc finalement d'avoir ma table avec mes données simplifiées et rangées par champ.


    Ce que je n'arrive pas à faire fonctionner (désolé) :

    • Tout ce que j'ai indiqué au dessus de manière automatique (hormis la fonction EXTRAC_BALISE). Je suis obligé de tout faire manuellement et en plus de passer par un document texte...

    • Il semble que LireHTML ne récupère pas la totalité de la page de code.

    Dans la fenêtre d'exécution immédiate, Il manque les 3 premiers quarts de la page et donc 100 enregistrements sur 139 (est-ce parce que la fenêtre à une limite de capacité ?)

    • Le texte généré par LireHTML ne se comporte pas comme le texte issu du code d'origine de la page.

    Si je fais un copier/coller du contenu de la fenêtre d'exécution immédiate obtenu par LireHTML vers un document texte et que j'applique mon processus, l'import dans une table donne des données incomplètes ou mal rangées (pas dans le bon champ).

    Ce que je souhaite à présent réaliser :

    Il est clair qu'il est possible de récupérer le contenu d'une page de code HTML et d'intervenir dessus, puisque LireHTML modifie la présentation des données de la page source et puisque dans les différentes propositions de code de marot_r (encore merci), on voit qu'on peut modifier la présentation des données.

    Il faudrait, idéalement, qu'une ou plusieurs fonctions remplissent les tâches suivantes :

    • Copier le contenu du code

    • Supprimer ce qui se trouve avant une balise (j'ai identifié laquelle pour chaque page, mais il serait souhaitable que je puisse renseigner cette balise, juste à côté de l'URL de la page souhaitée par exemple).

    De même si je pouvais aussi renseigner la balise de fin pour me débarrasser du bas de la page, ce ne serait que mieux.

    • Remplacer toutes les balises de fin de champ par un caractère séparateur (là aussi il serait bien que je puisse renseigner la balise)

    • Importer le résultat dans une table en utilisant le caractère séparateur indiqué ci-avant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Exemple :
    Importe(Remplace(SupprEntête_Pied(CopieCode (URL),BaliseDébutPage, BaliseFinPage)BaliseChamp;carractèreSépare);NomDeLaTable;carractèreSépare)
    Je pense que l'étape première va être de récupérer l'intégralité du code HTML, tel qu'il se présente dans la page web.

    J'ai déjà des pistes, mais c'est souvent vers Excel, ou vers un champ ou un contrôle d'un formulaire. Pas moyen de le garder en suspend le temps d'appliquer quelques interventions et ensuite l'importer dans une base...

    Encore un très grand merci pour votre aide.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Débutant] Récupérer des informations sur une page web
    Par Jules24 dans le forum Général Dotnet
    Réponses: 0
    Dernier message: 24/04/2012, 10h55
  2. récupérer des valeurs sur une page web
    Par houwa dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 11/07/2008, 14h27
  3. Réponses: 22
    Dernier message: 29/03/2007, 22h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo