Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 9 sur 9
  1. #1
    Candidat au titre de Membre du Club
    Homme Profil pro
    Inscrit en
    août 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : août 2009
    Messages : 26
    Points : 12
    Points
    12

    Par défaut BeautifulSoup - Recherche de données dans une page web

    Bonjour,

    Tout d'abord, je tiens à préciser que je débute en Python.

    Je cherche à récupérer des infos (Nom du film, nom du réalisateur, note …) dans une page web dont voici un extrait :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    			<!-- element -->
    			<div class="t12-crilst-item">
    				<p class="clear">&nbsp;</p>
    				<figure>				
    				<img src="http://medias-telerama.sdv.fr/cinemovies/posters/24072/tn-les-enfants-de-belle-ville-24072-575331289.jpg" alt="Les Enfants de Belle Ville">
     
    				</figure>
    			<div class="t12-crilst-crit">
    					<p class="t12-crilst-ulysse"><img src="http://icon-telerama.sdv.fr/label/cinema/grand/4.png" alt="On aime beaucoup"    title="On aime beaucoup" border="0"  /></p>
    					<p class="t12-crilst-avis">
    					<a  href="/cinema/films/les-enfants-de-belle-ville,434279.php">L'essentiel</a><br />
    			<a  href="/cinema/films/les-enfants-de-belle-ville,434279,critique.php">Critique</a><br />
    			<a  href="/cinema/films/les-enfants-de-belle-ville,434279,seances.php">Séances</a><br />
    			<a href="/cinema/films/les-enfants-de-belle-ville,434279,bande-annonce.php">Bandes-annonces</a><br />
    			<a  href="/cinema/films/les-enfants-de-belle-ville,434279,avis-spectateurs.php">Vos avis</a><br />
    			<a href="/cinema/films/les-enfants-de-belle-ville,434279,photos.php">Galerie photos</a><br />
    					</p>
    				</div>
    				<!--t12-crilst-crit-->
    				<blockquote>
    					<p class="t12-crilst-tit">
    					<a href="/cinema/films/les-enfants-de-belle-ville,434279.php">Les Enfants de Belle Ville (Shahr - Eziba)   réalisé par Asghar Farhadi </a>
    					</p>
    					<p class="t12-crilst-chapo">
    					Drame   avec Hossein Farzi-Zadeh  et Taraneh Alidousti  et Babak Ansari  et Faramars Gharibian  et Ahoo Kheradmand  et Farhad Ghaiemian  et Hooshang Heyhavand (1h41min)					</p>
     
    					<p class="t12-crilst-txt">
    					Le film est de 2004 mais on y sent d&eacute;j&agrave;, en germe, ce qui fera le succ&egrave;s d'&laquo; Une s&eacute;paration &raquo; : un sc&eacute;nario tr&egrave;s &eacute;crit, qui met en sc&egrave;ne un dilemme. Un jeune homme est condamn&eacute; &agrave; mort. Obtiendra-t-on sa gr&acirc;ce ? Lois civile et religieuse s'enchev&ecirc;trent dans un r&eacute;cit &agrave; suspense, toujours passionnant.					</p>
    				</blockquote>
    				<p class="clear">&nbsp;</p>
    			</div>
    			<!-- /element -->
    En faisant des recherches, j'ai pu me rendre compte que c'était une requête assez courante.
    Je voudrais le faire avec BeautifulSoup, mais je n'y arrive pas pour l'instant.
    Ce que je ne comprends pas, c'est comment repérer l'objet que je souhaite récupérer.
    J'ai vu qu'on pouvait le faire avec DOM Inspector (http://www.developpez.net/forums/d32...beautifulsoup/), mais DOM Inspector ne propose pas de TAG pour l'objet que je souhaite récupérer …

    Quelqu'un pourrait il me mettre sur la voie ?

    Merci d'avance.

  2. #2
    Expert Confirmé

    Homme Profil pro
    Inscrit en
    octobre 2008
    Messages
    1 884
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : octobre 2008
    Messages : 1 884
    Points : 2 896
    Points
    2 896

    Par défaut

    Bonjour,

    Tu peux récupérer les données avec findAll()

    Avec ton exemple:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
     
    # -*- coding: utf8 -*-
     
    import BeautifulSoup as BS
     
    PAGE = """<!-- element -->
    			<div class="t12-crilst-item">
    				<p class="clear">&nbsp;</p>
    				<figure>				
    				<img src="http://medias-telerama.sdv.fr/cinemovies/posters/24072/tn-les-enfants-de-belle-ville-24072-575331289.jpg" alt="Les Enfants de Belle Ville">
     
    				</figure>
    			<div class="t12-crilst-crit">
    					<p class="t12-crilst-ulysse"><img src="http://icon-telerama.sdv.fr/label/cinema/grand/4.png" alt="On aime beaucoup"    title="On aime beaucoup" border="0"  /></p>
    					<p class="t12-crilst-avis">
    					<a  href="/cinema/films/les-enfants-de-belle-ville,434279.php">L'essentiel</a><br />
    			<a  href="/cinema/films/les-enfants-de-belle-ville,434279,critique.php">Critique</a><br />
    			<a  href="/cinema/films/les-enfants-de-belle-ville,434279,seances.php">Seances</a><br />
    			<a href="/cinema/films/les-enfants-de-belle-ville,434279,bande-annonce.php">Bandes-annonces</a><br />
    			<a  href="/cinema/films/les-enfants-de-belle-ville,434279,avis-spectateurs.php">Vos avis</a><br />
    			<a href="/cinema/films/les-enfants-de-belle-ville,434279,photos.php">Galerie photos</a><br />
    					</p>
    				</div>
    				<!--t12-crilst-crit-->
    				<blockquote>
    					<p class="t12-crilst-tit">
    					<a href="/cinema/films/les-enfants-de-belle-ville,434279.php">Les Enfants de Belle Ville (Shahr - Eziba)   réalisé par Asghar Farhadi </a>
    					</p>
    					<p class="t12-crilst-chapo">
    					Drame   avec Hossein Farzi-Zadeh  et Taraneh Alidousti  et Babak Ansari  et Faramars Gharibian  et Ahoo Kheradmand  et Farhad Ghaiemian  et Hooshang Heyhavand (1h41min)					</p>
     
    					<p class="t12-crilst-txt">
    					Le film est de 2004 mais on y sent d&eacute;j&agrave;, en germe, ce qui fera le succ&egrave;s d'&laquo; Une s&eacute;paration &raquo; : un sc&eacute;nario tr&egrave;s &eacute;crit, qui met en sc&egrave;ne un dilemme. Un jeune homme est condamn&eacute; &agrave; mort. Obtiendra-t-on sa gr&acirc;ce ? Lois civile et religieuse s'enchev&ecirc;trent dans un r&eacute;cit &agrave; suspense, toujours passionnant.					</p>
    				</blockquote>
    				<p class="clear">&nbsp;</p>
    			</div>
    			<!-- /element -->"""
     
    def parse_page():
        soup = BS.BeautifulSoup(PAGE)
        print soup.findAll('p', {'class':'t12-crilst-txt'})
        print soup.findAll('div', {'class':'t12-crilst-crit'})
     
    if __name__ == '__main__':
        parse_page()
    Il faudra aussi gérer l'encodage de la page.



    Edit: Je met en attachement l'ancienne version du parser de Qarte (Arte+7), cette version utilisait BeautifullSoup que j'ai supprimé par après parce que beaucoup trop lent. je l'ai remplacé par des regex. Cette nouvelle version est ici:
    http://bazaar.launchpad.net/~vincent...ad:/parsers.py
    Fichiers attachés Fichiers attachés
    Vincent
    Oqapy . Qarte . PaQager

  3. #3
    Candidat au titre de Membre du Club
    Homme Profil pro
    Inscrit en
    août 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : août 2009
    Messages : 26
    Points : 12
    Points
    12

    Par défaut

    Merci pour ta réponse.

    Je digère tout ça et je reviens ...

  4. #4
    Candidat au titre de Membre du Club
    Homme Profil pro
    Inscrit en
    août 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : août 2009
    Messages : 26
    Points : 12
    Points
    12

    Par défaut

    Bon, j'ai testé le code que tu me proposes et ça ne me renvoie pas exactement ce que je cherche.
    J'aurais voulu obtenir quelque chose du genre :

    Titre du film : Les Enfants de Belle Ville
    Note : On aime beaucoup
    Réalisateur : Asghar Farhadi
    Acteurs : Hossein Farzi-Zadeh et Taraneh Alidousti et Babak Ansari et Faramars Gharibian et Ahoo Kheradmand et Farhad Ghaiemian et Hooshang Heyhavand (1h41min)

    Je crois que je vais finir par le faire avec des regex. C'est surement faisable de façon plus élégante avec un parser comme BS, mais je vais attendre de m'étoffer un peu en python avant !

  5. #5
    Candidat au titre de Membre du Club
    Homme Profil pro
    Inscrit en
    août 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : août 2009
    Messages : 26
    Points : 12
    Points
    12

    Par défaut

    J'ai terminé une première version de mon code et il fonctionne à peu près. J'ai finalement utilisé les regex :

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    # -*- coding: utf-8 -*-
    import re, urllib2
     
    regexNote=re.compile('.png\" alt=\"(.*)\"    title')
    regexTitre=re.compile('php\">(.*)    r\xe9alis\xe9')
    regexReal=re.compile('r\xe9alis\xe9 par (.*) </a>')
    Liste_Films = list()
    Film = list()
    Note = str()
    Titre = str()
    Real = str()
    i = 0
    j = 0
     
    the_url = 'http://www.telerama.fr/cine/film_datesortie.php?date=20120711'
    req = urllib2.Request(the_url)
    contenu = urllib2.urlopen(req)
    ligne = contenu.readline()
     
    while re.match("t12-crilst t12-crilst-film",ligne):
        ligne = contenu.readline()
     
    while i < 3:
        ligne = contenu.readline()
        Note = regexNote.search(ligne)
        Titre = regexTitre.search(ligne)
        Real = regexReal.search(ligne)
        if Note:
            NomNote = Note.group(1)
            Film.append(NomNote)
        if Titre:
            NomTitre = Titre.group(1)
            Film.append(NomTitre)
        if Real:
            NomReal = Real.group(1)
            Film.append(NomReal)
            Liste_Films.append(Film)
            Film = []
            i += 1
     
    while j < 3:
        print "Titre :",Liste_Films[j][1]
        print "Note  :",Liste_Films[j][0]
        print "Real  :",Liste_Films[j][2]
        print ""
        j += 1
    En fait, il me reste quelques petits problèmes :
    - Gérer les accents etc (j'ai mis un entête utf-8, mais visiblement, c'est plus compliqué que ça)
    - Quand dans mon champ "Titre" il y a des parenthèses (par exemple : "Le mur (The Wall)" ), ma regex (.*) ne le reconnait pas correctement.

    Sinon, n'hésitez pas à le critiquer, ça me fera progresser !

  6. #6
    Candidat au titre de Membre du Club
    Profil pro Pierre Quentel
    Inscrit en
    novembre 2009
    Messages
    10
    Détails du profil
    Informations personnelles :
    Nom : Pierre Quentel

    Informations forums :
    Inscription : novembre 2009
    Messages : 10
    Points : 14
    Points
    14

    Par défaut

    Bonjour,

    Le parsing d'un document HTML n'est pas une chose facile, il vaut mieux réutiliser les librairies faites pour ça que d'essayer avec des expressions régulières

    Pour ton exemple tu peux utiliser le module html.parser, en jouant sur les méthodes handle_starttag et handle_data de la classe HTMLParser. En Python3 voilà ce que ça peut donner :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
    src = "<le code source ici>"
     
    from html.parser import HTMLParser
     
    films = []
     
    class FilmParser(HTMLParser):
     
        current_key = None
     
        def handle_starttag(self,tag,attrs):
            if tag=='p':
                for (name,value) in attrs:
                    if name=="class":
                        if value == "t12-crilst-tit": # nouveau film
                            films.append({value:''})
                            self.current_key = value
                        elif value in ["t12-crilst-chapo","t12-crilst-txt"]:
                            films[-1][value]=''
                            self.current_key = value
     
        def handle_data(self,data):
            if self.current_key is not None:
                films[-1][self.current_key] += data
     
    root = FilmParser().feed(src)
    print(films)
    films est une liste de dictionnaires indexés par les noms de classe (que tu peux facilement transformer en des noms plus explicites comme "titre")

    - Pierre

  7. #7
    Candidat au titre de Membre du Club
    Homme Profil pro
    Inscrit en
    août 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : août 2009
    Messages : 26
    Points : 12
    Points
    12

    Par défaut

    Merci pour ton aide.

    Je teste ta solution dès que possible.

    Pierre (aussi)

  8. #8
    Candidat au titre de Membre du Club
    Homme Profil pro
    Inscrit en
    août 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : août 2009
    Messages : 26
    Points : 12
    Points
    12

    Par défaut

    Bon, je comprends mieux comment ça fonctionne.

    Par contre, j'ai un problème d'accent dans le document généré : le programme a tout simplement supprimé tous les caractères spéciaux (même pas remplacé par &eacute; ...).

    En tout cas, merci à vous, kervaker et VinsS pour votre aide.

  9. #9
    Candidat au titre de Membre du Club
    Homme Profil pro
    Inscrit en
    août 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : août 2009
    Messages : 26
    Points : 12
    Points
    12

    Par défaut

    Le script que tu m'as proposé, kervaker, me permet d'extraire pas mal d'informations que je cherchais.

    Cependant, il y en a d'autres que je n'arrive pas à extraire, comme l'adresse de l'affichette ou bien la note :
    <img src="http://medias-telerama.sdv.fr/cinemo...-575331289.jpg" alt="Les Enfants de Belle Ville">
    <p class="t12-crilst-ulysse"><img src="http://icon-telerama.sdv.fr/label/cinema/grand/4.png" alt="On aime beaucoup" title="On aime beaucoup" border="0" /></p>

    Et je ne comprends pas bien encore comment on navigue vers les différentes balises pour récupérer les différentes informations de la page : faut il décomposer la page html et suivre un "chemin" de balises ?
    Quand tu cherches à extraire une information, quelle est la marche à suivre pour demander à htmlparser de l'extraire ?

    Merci pour ton aide

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

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •