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

Python Discussion :

Beautiful soup et regex


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Curieux
    Inscrit en
    Avril 2020
    Messages
    114
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Curieux
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2020
    Messages : 114
    Par défaut Beautiful soup et regex
    Bonjour à tous,
    je tente de récupérer les données d'un tableau d'une page web. J'ai cru comprendre que Beautiful soup était un outil pour ce genre de manip.
    Je souhaiterais créer une liste par ligne du tableau avec les valeurs numériques dans l'idéal. voici ce que j'ai :
    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
    from bs4 import BeautifulSoup
    import re
     
    info = """
    <tr>
                    
                    <th style="font-size:1.25em">
                        <span class="tipsy-trigger" original-title="Heure réelle d'émission :&lt;br /&gt;02/08/2020&lt;br /&gt;&lt;b&gt;00h00 UTC&lt;/b&gt;">02h00</span>                </th>
     
                    
                    
                    <td style="/*background-color:rgba(0,0,0,0.1)*/"><span title="" class="" style="font-weight:bold;display:inline-block;font-size:16px">17.3</span> <span class="tab-units-v">°C</span><span class="color-heatmap" style="background-color:rgb(255,211,30)"></span></td><td style="padding-left:8px; padding-right:8px;"></td><td style="/*background-color:rgba(0,0,0,0.1)*/">0 <span class="tab-units-v">mm/1h</span><span class="color-heatmap" style="background-color:rgb(255,255,255)"></span><br><a href="javascript:void(0)" style="opacity:0.3;" class="tipsy-trigger button-rr-pluvio" original-title="&lt;table class='minitable-details' style='table-layout:fixed'&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Pluie/24h :&lt;/b&gt;&lt;/td&gt;&lt;td&gt;1.4mm&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;"><span></span></a></td><td style="padding-left:20px; white-space: nowrap;"><span style="font-weight:bold">0</span> <span class="tab-units-v">m/s</span><br><span class="tab-units-v">raf.</span><span style="font-weight:bold">0</span>                            <div style="position: absolute; left:0px; top:50%; margin-top:-10px; height:20px; width:20px; background-image:url(//static.infoclimat.net/images/pictos_vent2/sprite.png); background-position: 240px 0px" class="tipsy-trigger" original-title="Vent de direction 7°">
                                </div></td><td style="/*background-color:rgba(0,0,0,0.1)*/"><span style="font-weight:bold;display:inline-block">96</span><span class="tab-units-v">%</span><span class="color-heatmap" style="background-color:rgb(4,129,175)"></span></td><td></td><td style="/*background-color:rgba(0,0,0,0.1)*/"><span style="font-weight:bold;display:inline-block">16.7</span> <span class="tab-units-v">°C</span><span class="color-heatmap" style="background-color:rgb(255,223,22)"></span></td><td>1019.1<span class="tab-units-v">hPa</span><span class="color-heatmap" style="background-color:rgb(239,255,51)"></span><br>=</td>            </tr>
                            <tr>
                    
                    <th style="font-size:1.25em">
                        <span class="tipsy-trigger" original-title="Heure réelle d'émission :&lt;br /&gt;01/08/2020&lt;br /&gt;&lt;b&gt;23h30 UTC&lt;/b&gt;">01h30</span>                </th>
     
                    
                    
                    <td style="/*background-color:rgba(0,0,0,0.1)*/"><span title="" class="" style="font-weight:bold;display:inline-block;font-size:16px">17.4</span> <span class="tab-units-v">°C</span><span class="color-heatmap" style="background-color:rgb(255,209,31)"></span></td><td style="padding-left:8px; padding-right:8px;"></td><td style="/*background-color:rgba(0,0,0,0.1)*/"></td><td style="padding-left:20px; white-space: nowrap;"><span style="font-weight:bold">0</span> <span class="tab-units-v">m/s</span><br><span class="tab-units-v">raf.</span><span style="font-weight:bold">0</span>                            <div style="position: absolute; left:0px; top:50%; margin-top:-10px; height:20px; width:20px; background-image:url(//static.infoclimat.net/images/pictos_vent2/sprite.png); background-position: 240px 0px" class="tipsy-trigger" original-title="Vent de direction 7°">
                                </div></td><td style="/*background-color:rgba(0,0,0,0.1)*/"><span style="font-weight:bold;display:inline-block">96</span><span class="tab-units-v">%</span><span class="color-heatmap" style="background-color:rgb(4,129,175)"></span></td><td></td><td style="/*background-color:rgba(0,0,0,0.1)*/"><span style="font-weight:bold;display:inline-block">16.7</span> <span class="tab-units-v">°C</span><span class="color-heatmap" style="background-color:rgb(255,223,22)"></span></td><td>1019.6<span class="tab-units-v">hPa</span><span class="color-heatmap" style="background-color:rgb(246,255,25)"></span><br><img class="tipsy-trigger" style="height:12px" src="https://static.infoclimat.net/images/v5.2/down.png" alt="baisse" original-title="-0.3 hPa/3h"></td>            </tr>
                            <tr>
                    
                    <th style="font-size:1.25em">
                        <span class="tipsy-trigger" original-title="Heure réelle d'émission :&lt;br /&gt;01/08/2020&lt;br /&gt;&lt;b&gt;23h00 UTC&lt;/b&gt;">01h00</span>                </th>
     
                    
                    
                    <td style="/*background-color:rgba(0,0,0,0.1)*/"><span title="" class="" style="font-weight:bold;display:inline-block;font-size:16px">17.6</span> <span class="tab-units-v">°C</span><span class="color-heatmap" style="background-color:rgb(255,206,34)"></span></td><td style="padding-left:8px; padding-right:8px;"></td><td style="/*background-color:rgba(0,0,0,0.1)*/">0 <span class="tab-units-v">mm/1h</span><span class="color-heatmap" style="background-color:rgb(255,255,255)"></span></td><td style="padding-left:20px; white-space: nowrap;"><span style="font-weight:bold">0</span> <span class="tab-units-v">m/s</span><br><span class="tab-units-v">raf.</span><span style="font-weight:bold">0</span>                            <div style="position: absolute; left:0px; top:50%; margin-top:-10px; height:20px; width:20px; background-image:url(//static.infoclimat.net/images/pictos_vent2/sprite.png); background-position: 240px 0px" class="tipsy-trigger" original-title="Vent de direction 7°">
                                </div></td><td style="/*background-color:rgba(0,0,0,0.1)*/"><span style="font-weight:bold;display:inline-block">96</span><span class="tab-units-v">%</span><span class="color-heatmap" style="background-color:rgb(4,129,175)"></span></td><td></td><td style="/*background-color:rgba(0,0,0,0.1)*/"><span style="font-weight:bold;display:inline-block">17.2</span> <span class="tab-units-v">°C</span><span class="color-heatmap" style="background-color:rgb(255,213,29)"></span></td><td>1019.9<span class="tab-units-v">hPa</span><span class="color-heatmap" style="background-color:rgb(246,255,25)"></span><br>=</td>            </tr>
                            <tr>
                    
    </body>
    </html>
    """
    soup = BeautifulSoup(info,features="html.parser")
    heure = list()
    #heure, temperature, vitesse vent, vitesse raffale, direction, humidité, pt rosée, pression
     
    count = 0
    for p in soup.find_all('div'):
        print(count,p)
        print(re.findall('direction.*?style', p.text))
     
        count+=1
    print(soup.get_text())
    je récupére donc ceci :
    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
    0 <div class="tipsy-trigger" original-title="Vent de direction 7°" style="position: absolute; left:0px; top:50%; margin-top:-10px; height:20px; width:20px; background-image:url(//static.infoclimat.net/images/pictos_vent2/sprite.png); background-position: 240px 0px">
    </div>
    []
    1 <div class="tipsy-trigger" original-title="Vent de direction 7°" style="position: absolute; left:0px; top:50%; margin-top:-10px; height:20px; width:20px; background-image:url(//static.infoclimat.net/images/pictos_vent2/sprite.png); background-position: 240px 0px">
    </div>
    []
    2 <div class="tipsy-trigger" original-title="Vent de direction 7°" style="position: absolute; left:0px; top:50%; margin-top:-10px; height:20px; width:20px; background-image:url(//static.infoclimat.net/images/pictos_vent2/sprite.png); background-position: 240px 0px">
    </div>
    []
     
     
     
    02h00 
    17.3 °C0 mm/1h0 m/sraf.0 
    96%16.7 °C1019.1hPa= 
     
     
    01h30 
    17.4 °C0 m/sraf.0 
    96%16.7 °C1019.6hPa 
     
     
    01h00 
    17.6 °C0 mm/1h0 m/sraf.0 
    96%17.2 °C1019.9hPa=
    Je souhaite donc avoir ceci, une liste de tuple par ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [('02h00', '17.3 °C', '0 mm/1h', '0 m/s', 'raf.0 ', '7°', '96%', '16.7 °C', '1019.1hPa'), ('01h30', '17.4 °C', '0 mm/1h', '0 m/s', 'raf.0 ', '7°', '96%', '16.7 °C', '1019.6hPa'), ('01h00', '17.6 °C', '0 mm/1h', '0 m/s', 'raf.0 ', '7°', '96%', '17.2 °C', '1019.9hPa')]
    A savoir que la direction est la légende d'une image que je tente d'isoler avec un regex.
    Ma première question est : suis sur la bonne voie ?
    Ma deuxième est : si oui, de quelle manière puis isoler mes valeurs numériques pour construire mes tuples de préférence sans les unités ^^.

    Je cherche dans la doc de beautifulsoup sans trouver ou comprendre quelles autres méthodes utiliser...
    Je me casse les dents sur le regex aussi.

    merci de vos retours

  2. #2
    Expert confirmé Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 041
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 041
    Par défaut
    salut,

    en cherchant les tr au lieu des div ça fonctionne un peu mieux en l'occurrence
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for count, p in enumerate(soup.find_all('tr')):
        print(count, p.get_text(separator=' ').split())
    ce qui donne ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    0 ['02h00', '17.3', '°C', '0', 'mm/1h', '0', 'm/s', 'raf.', '0', '96', '%', '16.7', '°C', '1019.1', 'hPa', '=']
    1 ['01h30', '17.4', '°C', '0', 'm/s', 'raf.', '0', '96', '%', '16.7', '°C', '1019.6', 'hPa']
    2 ['01h00', '17.6', '°C', '0', 'mm/1h', '0', 'm/s', 'raf.', '0', '96', '%', '17.2', '°C', '1019.9', 'hPa', '=']
    3 []
    avec lequel tu dois pouvoir retomber facilement sur tes pattes

  3. #3
    Expert confirmé
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 199
    Par défaut
    hello,
    Aerulus_ ta chaîne html qui semble être une partie extraite d'une page html, n'est pas correcte. En effet à la fin on a :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
               </tr>
    </body>
    </html>
    des balises fermantes sans leurs balises ouvrantes. Ceci produit une ligne en trop dans le résultat du code de BufferBob :
    3[]
    Tu n'as pas besoin d'utiliser d'expressions régulières pour récupérer la direction du vent sur chacune des lignes de la table.
    Dans ces lignes la direction du vent est dans une balise div. Avec BeautifulSoup, il suffit de récupérer cette balise div et d'en extraire le contenu de l'attribut original-title
    En reprenant le code de BufferBob voici comment faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    count = 0
    for count, p in enumerate(soup.find_all('tr')):
        # on cherche  le div dans les tr (direction du vent)
        div_dir_vent = p.find("div")
        # on récupère le contenu de l'attribut original-title du div
        if div_dir_vent is not None:
            dir_vent = div_dir_vent.get('original-title')
        else:
            dir_vent = '?'
        print(count, p.get_text(separator=' ').split(), dir_vent)
    #
    et voici le résultat :
    0 ['02h00', '17.3', '°C', '0', 'mm/1h', '0', 'm/s', 'raf.', '0', '96', '%', '16.7', '°C', '1019.1', 'hPa', '='] Vent de direction 7°
    1 ['01h30', '17.4', '°C', '0', 'm/s', 'raf.', '0', '96', '%', '16.7', '°C', '1019.6', 'hPa'] Vent de direction 7°
    2 ['01h00', '17.6', '°C', '0', 'mm/1h', '0', 'm/s', 'raf.', '0', '96', '%', '17.2', '°C', '1019.9', 'hPa', '='] Vent de direction 7°
    Ami calmant, J.P

  4. #4
    Membre confirmé
    Homme Profil pro
    Curieux
    Inscrit en
    Avril 2020
    Messages
    114
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Curieux
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2020
    Messages : 114
    Par défaut
    Bonjour tous les deux,
    c'est super...

    Citation Envoyé par BufferBob Voir le message
    salut,

    en cherchant les tr au lieu des div ça fonctionne un peu mieux en l'occurrence
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for count, p in enumerate(soup.find_all('tr')):
        print(count, p.get_text(separator=' ').split())
    Effectivement les [c]tr[/] permettent de tout récupérer, je n'arrivais simplement pas à utiliser p.get_text() ou pas de manière efficace.

    Citation Envoyé par jurassic pork Voir le message
    hello,
    Aerulus_ ta chaîne html qui semble être une partie extraite d'une page html, n'est pas correcte. En effet à la fin on a :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
               </tr>
    </body>
    </html>
    des balises fermantes sans leurs balises ouvrantes. Ceci produit une ligne en trop dans le résultat du code de BufferBob
    Oui jurassic pork, tu as entierement raison, j'ai tronquer le code de la page à la sauvage pour l'exemple. Avec le code complet de la page il n'y a pas le [] vide.
    Et je n'avais pas non plus pensé à directement extraire l'attribut du div, bien plus simple que ma démarche avec les regex.
    J'ai effectivement grace à vous les éléments pour tracer les info de la page.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    donnee = list()
    for count, p in enumerate(soup.find_all('tr')):
        # on cherche  le div dans les tr (direction du vent)
        div_dir_vent = p.find("div")
        # on récupère le contenu de l'attribut original-title du div
        if div_dir_vent is not None:
            dir_vent = div_dir_vent.get('original-title')
        else:
            dir_vent = '?'
        #print(count, p.get_text(separator=' ').split(), dir_vent)
        if dir_vent:#permet de filtreer la premiere ligne (ligne des titres)
            #print(re.findall('\d+', str(dir_vent))[0])#extraction de la valeur numérique de la direction
            donnee.append((count, p.get_text(separator=' ').split(),
                           re.findall('\d+', str(dir_vent))[0]))#recuperation de toutes les donnees isolees dans une liste
    cool,cool,cool.
    Merci

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

Discussions similaires

  1. [Python 3.X] Récupérer données avec Beautiful Soup
    Par TheSeacfr dans le forum Général Python
    Réponses: 2
    Dernier message: 28/08/2019, 13h09
  2. [Python 2.X] Parser HTML et Beautiful Soup
    Par Invité dans le forum Général Python
    Réponses: 11
    Dernier message: 26/10/2014, 15h03
  3. beautiful soup get content
    Par napoleon59 dans le forum Général Python
    Réponses: 1
    Dernier message: 02/06/2014, 00h16
  4. [regex][string] replaceAll bogué ?
    Par 7eme dans le forum Collection et Stream
    Réponses: 4
    Dernier message: 13/11/2003, 16h36
  5. Cherche regex...
    Par laurent_h dans le forum C
    Réponses: 4
    Dernier message: 31/03/2003, 11h24

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