Précédent   Forum du club des développeurs et IT Pro > Autres langages > Python & Zope > Réseau/Web
Réseau/Web Forum d'entraide sur Python et le réseau/Web
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 11/07/2012, 13h18   #1
Okidor12
Invité de passage
 
Inscription : août 2009
Messages : 20
Détails du profil
Informations forums :
Inscription : août 2009
Messages : 20
Points : 4
Points : 4
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.
Okidor12 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/07/2012, 15h12   #2
VinsS
Membre Expert
 
Homme
Inscription : octobre 2008
Messages : 972
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Belgique

Informations forums :
Inscription : octobre 2008
Messages : 972
Points : 1 454
Points : 1 454
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
Type de fichier : py parser.py (7,2 Ko, 3 affichages)
__________________
Vincent
Oqapy . Qarte . PaQager
VinsS est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/07/2012, 15h52   #3
Okidor12
Invité de passage
 
Inscription : août 2009
Messages : 20
Détails du profil
Informations forums :
Inscription : août 2009
Messages : 20
Points : 4
Points : 4
Merci pour ta réponse.

Je digère tout ça et je reviens ...
Okidor12 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/07/2012, 09h07   #4
Okidor12
Invité de passage
 
Inscription : août 2009
Messages : 20
Détails du profil
Informations forums :
Inscription : août 2009
Messages : 20
Points : 4
Points : 4
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 !
Okidor12 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/07/2012, 09h48   #5
Okidor12
Invité de passage
 
Inscription : août 2009
Messages : 20
Détails du profil
Informations forums :
Inscription : août 2009
Messages : 20
Points : 4
Points : 4
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 !
Okidor12 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/07/2012, 10h52   #6
kervarker
Candidat au titre de Membre du Club
 
Pierre Quentel
Inscription : novembre 2009
Messages : 10
Détails du profil
Informations personnelles :
Nom : Pierre Quentel

Informations forums :
Inscription : novembre 2009
Messages : 10
Points : 11
Points : 11
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
kervarker est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/07/2012, 10h30   #7
Okidor12
Invité de passage
 
Inscription : août 2009
Messages : 20
Détails du profil
Informations forums :
Inscription : août 2009
Messages : 20
Points : 4
Points : 4
Merci pour ton aide.

Je teste ta solution dès que possible.

Pierre (aussi)
Okidor12 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/07/2012, 09h14   #8
Okidor12
Invité de passage
 
Inscription : août 2009
Messages : 20
Détails du profil
Informations forums :
Inscription : août 2009
Messages : 20
Points : 4
Points : 4
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.
Okidor12 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/07/2012, 10h36   #9
Okidor12
Invité de passage
 
Inscription : août 2009
Messages : 20
Détails du profil
Informations forums :
Inscription : août 2009
Messages : 20
Points : 4
Points : 4
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
Okidor12 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 00h32.


 
 
 
 
Partenaires

Hébergement Web