[Python] HTML parsing
Fermé
dje-dje
Messages postés
10417
Date d'inscription
mardi 6 janvier 2004
Statut
Modérateur
Dernière intervention
28 janvier 2011
-
8 avril 2004 à 15:20
sebsauvage Messages postés 32893 Date d'inscription mercredi 29 août 2001 Statut Modérateur Dernière intervention 21 octobre 2019 - 6 févr. 2005 à 12:42
sebsauvage Messages postés 32893 Date d'inscription mercredi 29 août 2001 Statut Modérateur Dernière intervention 21 octobre 2019 - 6 févr. 2005 à 12:42
A voir également:
- [Python] HTML parsing
- Editeur html - Télécharger - HTML
- Citizen code python avis - Accueil - Outils
- &Nbsp html ✓ - Forum Webmastering
- Br html ✓ - Forum Webmastering
13 réponses
sebsauvage
Messages postés
32893
Date d'inscription
mercredi 29 août 2001
Statut
Modérateur
Dernière intervention
21 octobre 2019
15 659
26 avril 2004 à 16:48
26 avril 2004 à 16:48
Une expression régulière pourrait suffire, je pense.
Ou même sans. Un simple .find() pourrait faire l'affaire.
Petit exemple avec find:
Ce programme va afficher:
A cause de la façon dont est implémenté .find(), ce bout de code est plus rapide que les expressions régulière, et aussi plus rapide que l'utilisation d'un parseur (SGMLParser ou HTMLParser).
Mais bien sûr rien ne t'empêche d'utiliser HTMLParser: tu peux récupérer les commentaires par la méthode handle_comment(data).
Ou même sans. Un simple .find() pourrait faire l'affaire.
Petit exemple avec find:
# -*- coding: iso-8859-1 -*- # Nos données à tester: data = """aaaa<!-- Begin : Toto -->bbb<!-- End : Toto est OK -->ccc <!-- Begin : Toto --> Encore un autre ! dddd<!-- End : Toto est OK -->""" beginTag = "<!-- Begin : Toto -->" endTag = "<!-- End : Toto est OK -->" startPos = data.find(beginTag) while startPos > -1: endPos = data.find(endTag,startPos+1) if endTag == -1: break else: print "Trouvé:",data[startPos+len(beginTag):endPos] startPos = data.find(beginTag,endPos+1)
Ce programme va afficher:
Trouvé: bbb Trouvé: Encore un autre ! dddd
A cause de la façon dont est implémenté .find(), ce bout de code est plus rapide que les expressions régulière, et aussi plus rapide que l'utilisation d'un parseur (SGMLParser ou HTMLParser).
Mais bien sûr rien ne t'empêche d'utiliser HTMLParser: tu peux récupérer les commentaires par la méthode handle_comment(data).
sebsauvage
Messages postés
32893
Date d'inscription
mercredi 29 août 2001
Statut
Modérateur
Dernière intervention
21 octobre 2019
15 659
8 avril 2004 à 15:44
8 avril 2004 à 15:44
Il faut utiliser handle_data().
Prend mon programme http://sebsauvage.net/python/html2csv.py
C'est un exemple d'utilisation de HTMLParser:
ça convertis tous les tableaux HTML trouvés en un fichier CSV (pour chargement dans Excel).
Le truc est d'avoir un flag (booléen) qui t'indique si tu es à l'intérieur du tag ou non.
handle_starttag() mettra ce flag à vrai.
handle_endtag() mettra ce flag à faux.
handle_data() ne gardera les données que si le flag est à vrai.
(dans mon programme, j'ai plusieurs flags : inTD (suis-je dans un tag TD ?), inTR, etc.)
Le pseudo-code serait:
Note que HTMLParser n'est que l'une des nombreuses manière de parser du HTML.
Tu pourrais aussi passer par d'autres API comme DOM ou SAX (je ne maîtrise pas, et ça nécessite l'installation de librairies supplémentaires.)
Il existe plusieurs librairies différentes pour DOM et SAX, plus ou moins grosses... euh complexes je voulais dire.
Prend mon programme http://sebsauvage.net/python/html2csv.py
C'est un exemple d'utilisation de HTMLParser:
ça convertis tous les tableaux HTML trouvés en un fichier CSV (pour chargement dans Excel).
Le truc est d'avoir un flag (booléen) qui t'indique si tu es à l'intérieur du tag ou non.
handle_starttag() mettra ce flag à vrai.
handle_endtag() mettra ce flag à faux.
handle_data() ne gardera les données que si le flag est à vrai.
(dans mon programme, j'ai plusieurs flags : inTD (suis-je dans un tag TD ?), inTR, etc.)
Le pseudo-code serait:
class monparseur: def __init__(): self.inMONTAG = false def handle_starttag(): Si tag=="MONTAG": self.inMONTAG=true def handle_endttag(): Si tag=="MONTAG": self.inMONTAG=false def handle_data(): Si self.inMONTAG==true: affiche "J'ai trouvé un tag <MONTAG> contenant:",data
Note que HTMLParser n'est que l'une des nombreuses manière de parser du HTML.
Tu pourrais aussi passer par d'autres API comme DOM ou SAX (je ne maîtrise pas, et ça nécessite l'installation de librairies supplémentaires.)
Il existe plusieurs librairies différentes pour DOM et SAX, plus ou moins grosses... euh complexes je voulais dire.
dje-dje
Messages postés
10417
Date d'inscription
mardi 6 janvier 2004
Statut
Modérateur
Dernière intervention
28 janvier 2011
758
8 avril 2004 à 16:07
8 avril 2004 à 16:07
J'y avaisi pensé mais ça n'a pas fonctionné. (J'avais mis le flag en variable globale et pas comme donnée de la classe comme tu sembles le préconiser)
En faisant comme tu dis, j'ai une erreur, sans doute lié à ma méconnaissance (encore!) de la fonction __init__
Je te mets mon code pour que tu me dise ce qui va pas:
class MyHTMLParser(HTMLParser):
def __init__():
self.InMonTag = 0
def handle_data(self,data):
if InMonTag==1:
print data
def handle_starttag(self, tag, attrs): # j'utilise les attributs
if tag == 'CeQueJeVeux':
self.InMonTag = 1
p = MyHTMLParser()
file = open('MonFichier','r')
chaine = file.read()
p.feed(chaine)
p.close()
Et il m'insulte avec ça:
p = MyHTMLParser()
TypeError: __init__() takes no arguments (1 given)
a+
dje-dje
Merci de ton aide
Il y a 10 types de personne dans le monde,
ceux qui comprennent le binaire et les autres
En faisant comme tu dis, j'ai une erreur, sans doute lié à ma méconnaissance (encore!) de la fonction __init__
Je te mets mon code pour que tu me dise ce qui va pas:
class MyHTMLParser(HTMLParser):
def __init__():
self.InMonTag = 0
def handle_data(self,data):
if InMonTag==1:
print data
def handle_starttag(self, tag, attrs): # j'utilise les attributs
if tag == 'CeQueJeVeux':
self.InMonTag = 1
p = MyHTMLParser()
file = open('MonFichier','r')
chaine = file.read()
p.feed(chaine)
p.close()
Et il m'insulte avec ça:
p = MyHTMLParser()
TypeError: __init__() takes no arguments (1 given)
a+
dje-dje
Merci de ton aide
Il y a 10 types de personne dans le monde,
ceux qui comprennent le binaire et les autres
sebsauvage
Messages postés
32893
Date d'inscription
mercredi 29 août 2001
Statut
Modérateur
Dernière intervention
21 octobre 2019
15 659
8 avril 2004 à 16:31
8 avril 2004 à 16:31
Ah... __init__().
Il faut que tu jette un coup d'oeil du côté programmation objet en Python.
__init__(self) est le constructeur.
Il est appelé quand la classe est créée.
Il doit être toujours déclaré avec au minimum 1 argument:
def __init__(self):
self.InMonTag=0 sert à créer une variable local à l'objet (spécifique à cet objet). (Aussi appelé "attribut" de l'objet.)
Attention: dans ton handle_data(), tu a utilisé InMonTag, qui est une variable locale à la fonction handle_data(). C'est donc une variable différente de self.InMonTag !
Il faut mettre explicitement self.InMonTag pour se référer à la variable déclarée dans le constructeur.
--> je te suggère de lire ce qui concerne le scope des objets en Python.
:-)
Si tu as des questions, n'hésite pas !
PS: Je ne me connecterai probablement de demain (vendredi) jusqu'à lundi. Je ne serai donc de retour que mardi.
Il faut que tu jette un coup d'oeil du côté programmation objet en Python.
__init__(self) est le constructeur.
Il est appelé quand la classe est créée.
Il doit être toujours déclaré avec au minimum 1 argument:
def __init__(self):
self.InMonTag=0 sert à créer une variable local à l'objet (spécifique à cet objet). (Aussi appelé "attribut" de l'objet.)
Attention: dans ton handle_data(), tu a utilisé InMonTag, qui est une variable locale à la fonction handle_data(). C'est donc une variable différente de self.InMonTag !
Il faut mettre explicitement self.InMonTag pour se référer à la variable déclarée dans le constructeur.
--> je te suggère de lire ce qui concerne le scope des objets en Python.
:-)
Si tu as des questions, n'hésite pas !
PS: Je ne me connecterai probablement de demain (vendredi) jusqu'à lundi. Je ne serai donc de retour que mardi.
dje-dje
Messages postés
10417
Date d'inscription
mardi 6 janvier 2004
Statut
Modérateur
Dernière intervention
28 janvier 2011
758
8 avril 2004 à 16:37
8 avril 2004 à 16:37
Ok, j'ai déjà fait de l'objet mais en C++, donc je suis familié des concept d'attribut (ou donnée membre), mais la syntaxe me laisse encore perplexe.
Encore merci et Bon (et Gros dis donc!) Week-end!
a+
dje-dje
Il y a 10 types de personne dans le monde,
ceux qui comprennent le binaire et les autres
Encore merci et Bon (et Gros dis donc!) Week-end!
a+
dje-dje
Il y a 10 types de personne dans le monde,
ceux qui comprennent le binaire et les autres
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
dje-dje
Messages postés
10417
Date d'inscription
mardi 6 janvier 2004
Statut
Modérateur
Dernière intervention
28 janvier 2011
758
8 avril 2004 à 16:41
8 avril 2004 à 16:41
Zut, j'ai rajouté le self dans la définition du __init__ et maintenant, j'ai ça:
self.rawdata = self.rawdata + data
AttributeError: MyHTMLParser instance has no attribute 'rawdata'
Je vais lire un peu de Doc moi ;-)
a+
Il y a 10 types de personne dans le monde,
ceux qui comprennent le binaire et les autres
self.rawdata = self.rawdata + data
AttributeError: MyHTMLParser instance has no attribute 'rawdata'
Je vais lire un peu de Doc moi ;-)
a+
Il y a 10 types de personne dans le monde,
ceux qui comprennent le binaire et les autres
sebsauvage
Messages postés
32893
Date d'inscription
mercredi 29 août 2001
Statut
Modérateur
Dernière intervention
21 octobre 2019
15 659
8 avril 2004 à 17:07
8 avril 2004 à 17:07
Il faut déclarer ton self.rawdata dans ton constructeur.
(Même si c'est pour mettre None dedans).
self.rawdata = None
(Même si c'est pour mettre None dedans).
self.rawdata = None
dje-dje
Messages postés
10417
Date d'inscription
mardi 6 janvier 2004
Statut
Modérateur
Dernière intervention
28 janvier 2011
758
8 avril 2004 à 17:07
8 avril 2004 à 17:07
J'ai changé 2 trucs:
(En m'inspirant méchamment de ton code ;-) )
import HTMLParser (au lieu de import HTMLParser from HTMLParser)
et
def __init__(self):
HTMLParser.HTMLParser.__init__(self)
self.InMonTag = 0
(au lieu de la précédente)
ca marche, mais j'ai fait quoi?
a+
dje-dje
En tout cas merci
Il y a 10 types de personne dans le monde,
ceux qui comprennent le binaire et les autres
(En m'inspirant méchamment de ton code ;-) )
import HTMLParser (au lieu de import HTMLParser from HTMLParser)
et
def __init__(self):
HTMLParser.HTMLParser.__init__(self)
self.InMonTag = 0
(au lieu de la précédente)
ca marche, mais j'ai fait quoi?
a+
dje-dje
En tout cas merci
Il y a 10 types de personne dans le monde,
ceux qui comprennent le binaire et les autres
dje-dje
Messages postés
10417
Date d'inscription
mardi 6 janvier 2004
Statut
Modérateur
Dernière intervention
28 janvier 2011
758
15 avril 2004 à 11:53
15 avril 2004 à 11:53
Si tu pouvais répondre à ma question du message <6> (t'as pas du la voir, il a été posté en même temps que ton <7>)
a+
dje-dje
Il y a 10 types de personne dans le monde,
ceux qui comprennent le binaire et les autres
a+
dje-dje
Il y a 10 types de personne dans le monde,
ceux qui comprennent le binaire et les autres
sebsauvage
Messages postés
32893
Date d'inscription
mercredi 29 août 2001
Statut
Modérateur
Dernière intervention
21 octobre 2019
15 659
15 avril 2004 à 12:03
15 avril 2004 à 12:03
Ah... il faut toujours impérativement appeler le constructeur de la classe mère, sinon ton objet n'est pas dans un état correct.
(C'est le HTMLParser.HTMLParser.__init__(self) que tu as fait.)
(C'est le HTMLParser.HTMLParser.__init__(self) que tu as fait.)
dje-dje
Messages postés
10417
Date d'inscription
mardi 6 janvier 2004
Statut
Modérateur
Dernière intervention
28 janvier 2011
758
15 avril 2004 à 12:13
15 avril 2004 à 12:13
Ok...
Mon objectif est d'aspirer le site des pages jaunes pour des sections que j'ai choisi. (Avec mon parser, j'essaie de virer ce qui n'est pas intéressant:pub,blabla,...)
En fait, je comptais utiliser urllib en m'inspirant - encore - de ton code, mais l'url ne change pas: c'est toujours le même script cgi qui est appelé et ils ne passent aucun paramètres dans l'url
Penses-tu que c'est possible de réaliser cet aspirateur de pages jaunes en python?
a+
dje-dje
Il y a 10 types de personne dans le monde,
ceux qui comprennent le binaire et les autres
Mon objectif est d'aspirer le site des pages jaunes pour des sections que j'ai choisi. (Avec mon parser, j'essaie de virer ce qui n'est pas intéressant:pub,blabla,...)
En fait, je comptais utiliser urllib en m'inspirant - encore - de ton code, mais l'url ne change pas: c'est toujours le même script cgi qui est appelé et ils ne passent aucun paramètres dans l'url
Penses-tu que c'est possible de réaliser cet aspirateur de pages jaunes en python?
a+
dje-dje
Il y a 10 types de personne dans le monde,
ceux qui comprennent le binaire et les autres
dje-dje
Messages postés
10417
Date d'inscription
mardi 6 janvier 2004
Statut
Modérateur
Dernière intervention
28 janvier 2011
758
23 avril 2004 à 15:46
23 avril 2004 à 15:46
Up!
a+
dje-dje
Il y a 10 types de personne dans le monde,
ceux qui comprennent le binaire et les autres
a+
dje-dje
Il y a 10 types de personne dans le monde,
ceux qui comprennent le binaire et les autres
sebsauvage
Messages postés
32893
Date d'inscription
mercredi 29 août 2001
Statut
Modérateur
Dernière intervention
21 octobre 2019
15 659
23 avril 2004 à 18:33
23 avril 2004 à 18:33
c'est toujours le même script cgi qui est appelé et ils ne passent aucun paramètres dans l'url
Penses-tu que c'est possible de réaliser cet aspirateur de pages jaunes en python?
C'est parceque ce sont des requêtes en mode POST.
On peut parfaitement en faire en Python, aucun problème.
Ton projet est tout à fait réalisable en Python.
Penses-tu que c'est possible de réaliser cet aspirateur de pages jaunes en python?
C'est parceque ce sont des requêtes en mode POST.
On peut parfaitement en faire en Python, aucun problème.
Ton projet est tout à fait réalisable en Python.
dje-dje
Messages postés
10417
Date d'inscription
mardi 6 janvier 2004
Statut
Modérateur
Dernière intervention
28 janvier 2011
758
26 avril 2004 à 09:25
26 avril 2004 à 09:25
Ok, merci beaucoup!
a+
dje-dje
Il y a 10 types de personne dans le monde,
ceux qui comprennent le binaire et les autres
a+
dje-dje
Il y a 10 types de personne dans le monde,
ceux qui comprennent le binaire et les autres
5 févr. 2005 à 18:06
Dis moi, au sujet du parsing html, j'aimerais le faire mais pour une URL. Est-ce possible ?
6 févr. 2005 à 12:42
et voilà !