Regexp et HTML

jeanphi6 Messages postés 33 Date d'inscription samedi 2 avril 2005 Statut Membre Dernière intervention 24 juillet 2008 - 21 mai 2007 à 17:37
jeanphi6 Messages postés 33 Date d'inscription samedi 2 avril 2005 Statut Membre Dernière intervention 24 juillet 2008 - 23 mai 2007 à 14:07
Bonjour, je suis sur un problème concernant les regexp et du HTML.

Je dois faire une application qui parse une page HTML et je voudrais faire une méthode qui me permette de récupérer tous les éléments dont la balise est passée en paramêtre. J'ai mon expression régulière qui est de cette forme :

"<"+balise+"(.*?>(.*?)</"+balise+">|.*?>|\\s.*?[^>'"]?>)"   

Mais je suis tombé sur un problème : en parsant la balise img sur la page principale du site, je suis tombé sur un élément ...
Ma première occurrence fut alors un énorme pavé de code commençant par une image et se terminant par (logique en meme temps) mais sauf que cette occurence aurait du s'arrêter juste après la balise img... je ne sais pas si vous visualisez mon problème ....

Je vous copie colle le résultat que j'ai  :

1er résultat :

Besoin d'aide dans un autre langage ?
.... alt="Google">

Par contre les autres résultats sont corrects :

Si quelqu'un pourrait m'aider, ce  serait sympa.

11 réponses

cs_AlexN Messages postés 694 Date d'inscription lundi 5 décembre 2005 Statut Membre Dernière intervention 8 janvier 2014 19
21 mai 2007 à 18:33
sauf que cette occurence aurait du s'arrêter juste après la balise img

Non puisque dans ton expression régulière tu demandes de prendre en considération la balise fermante.
si tu ne veux pas capturer les balises fermantes, enlèves les de ton expression

Sinon une solution beaucoup plus simple est d'utiliser une librairie comme htmlparser

NodeList imagesList = parser.parse(new NodeClassFilter (ImageTag.class));

et tu recupères une liste des tous les tag images, y'a plus qu'a iterer dessus
0
jeanphi6 Messages postés 33 Date d'inscription samedi 2 avril 2005 Statut Membre Dernière intervention 24 juillet 2008
21 mai 2007 à 18:43
A oui je ne veux pas utiliser de librairies externes (j'ai aussi abordé le sujet du choix du parser et on m'a conseillé les expressions régulières).

"sauf que cette occurence aurait du s'arrêter juste après la balise img"
J'aurais bien voulu
0
cs_AlexN Messages postés 694 Date d'inscription lundi 5 décembre 2005 Statut Membre Dernière intervention 8 janvier 2014 19
21 mai 2007 à 18:56
On t'a conseillé ? Celui qui t'a conseillé semble vouloir te faire suer pour rien. Pourquoi reconstruire les expressions régulières de capture des tags images quand d'autres l'on déjà fait ?
Un autre soucis de ton expression régulière est le motif .*, je ne suis pas sur mais je crois qu'avec un motif comme celui là, la résolution du motif complet est en bestfit et non en firstfit. (voir l'option DOTALL) C'est à dire que la chaine qui sera pris en considération sera la plus longue possible. Il faudrait être plus précis dans les motifs comme par exemple remplacer le premier .* par [^>]*. Cad au lieu de lui demander "prend tout" tu demandes "prend tout sauf le caractère qui commence un nouveau motif (ici le caractère >).
0
jeanphi6 Messages postés 33 Date d'inscription samedi 2 avril 2005 Statut Membre Dernière intervention 24 juillet 2008
21 mai 2007 à 19:05
"prend tout sauf le caractère qui commence un nouveau motif (ici le caractère >)"

mais si une balise contient une autre balise (par exemple une balise li qui contient un lien () ?

Je dois faire sans librairies externes, je dois me servir quede l'api...

"motif complet est en bestfit et non en firstfit. "
je vais me renseigner de ce coté.

Merci
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_AlexN Messages postés 694 Date d'inscription lundi 5 décembre 2005 Statut Membre Dernière intervention 8 janvier 2014 19
21 mai 2007 à 21:56
Si tu veux vraiment capturer toutes les balises des certaines pages uniquement avec des expressions régulières, tu dois :


- analyser toi même le html des pages cibles et plus particulièrement les régions qui contiennent ce que tu veux capturer, personne ne peut le faire à ta place

- en déduire les expressions qui permettront ces captures dans le cas particulier de tes pages

- faire une veille automatique ou manuelle pour que lorsque l'auteur
ou un programme modifie les pages cibles, tu puisses éventuellement ajuster les expressions que tu
as écrites, recompiler et relancer ton programme pour qu'il reste capable de capturer les mêmes
éléments, parce que oui le html ca peut bouger, alors que non les
expressions régulières elles sont figées, elles sont compilées.

html est un cousin éloigné de xml qui est lui même un enfant de sgml. sgml est plutot un concept, xml un modèle exploitable par les programmes et html un sous modèle exploitable par nous les humains.
Malgré les standards, html c'est n'importe quoi. L'écriture (émission) d'un même document - contenant la même information - dépend du contcxte (l'auteur, logiciel de rédaction...) et sa lecture (reception) dépend d'un autre contexte (lecteur, capacités de la machine qui le reçoit - matériel, OS, navigateur...).

Analyser du html à l'aide seulement avec des expressions régulières c'est au plus hasardeux.

Je ne vois que peu raisons pour qu'on t'empêche d'utiliser autre choses "que les api". htmlparser est une librairie qui dispose elle aussi de sa propre api - d'objets.
Ton application doit s'éxécuter dans un environnement restreint : multithread avec temps de réponse controlable, espace mémoire très limité, temps de réponse très limité ou temps réel...
S'il s'agit d'une application qui doit attendre les réponses des utilisateurs ou qui peu consommer un peu de ressource pour améliorer la qualité de ses résultats, alors autant utiliser des librairies qui résolvent beaucoup de ces problèmes auxquels tu te heurtes comme dans la capture d'une classe de balise particulière

A mon avis revois ta position sur l'utilisation d'outils externes, on est plus à l'âge de pierre.
0
jeanphi6 Messages postés 33 Date d'inscription samedi 2 avril 2005 Statut Membre Dernière intervention 24 juillet 2008
21 mai 2007 à 22:51
je sais bien que le HTML c'est du n'importe quoi, je l'ai bien vu, je viens de trouver un cas où mon expression régulière ne fonctionnait plus. Cependant avant elle marchait bien, donc je me disais qu'en modifiant un truc ou deux, cela pourrait corriger le problème.

je vais en re-parler de l'utilisation d'une librairie externe, mais ce n'est pas pour autant que ce choix sera respecté.

Merci bien pour ta réponse ;)
0
jeanphi6 Messages postés 33 Date d'inscription samedi 2 avril 2005 Statut Membre Dernière intervention 24 juillet 2008
22 mai 2007 à 08:42
Je viens de tester le htmlparser, mais deux questions me viennent en tête :

Peut-on parser toutes les balises HTML (j'ai vu une liste mais elle ne me parait pas complète) ?

Peut-on récupérer les attributs facilement avec cette librairie?
0
cs_AlexN Messages postés 694 Date d'inscription lundi 5 décembre 2005 Statut Membre Dernière intervention 8 janvier 2014 19
22 mai 2007 à 10:08
1) Oui bien sur :

Parser parser = new Parser ("http://whatever");
NodeList list = parser.parse (null);
// do something with your list of nodes.

consultes la javadoc : http://htmlparser.sourceforge.net/javadoc/index.html

2) oui

tagNode.getAttribute(attributeName)
0
jeanphi6 Messages postés 33 Date d'inscription samedi 2 avril 2005 Statut Membre Dernière intervention 24 juillet 2008
22 mai 2007 à 11:26
1) oui oui tu me l'avais montré plus haut, mais ce que je demandais, c'était si on pouvais lui demander de parser telle ou telle balise, genre "a" ou "img".
j'avais pas lu entièrement la doc , je viens de trouver ça
nl.extractAllNodesThatMatch (new TagNameFilter ("HEAD"))

Mais ça marche pas .... j'ai mis head, HEAD, a , A, img, IMG ça me donne une liste toujours vide.

2) J'avais pas vu que Node était une interface :)
0
cs_AlexN Messages postés 694 Date d'inscription lundi 5 décembre 2005 Statut Membre Dernière intervention 8 janvier 2014 19
22 mai 2007 à 11:39
As tu verifié que ton parser a été correctement initalisé, qu'il contient bien l'arbre du document ?
Tu n'as pas du lire correctement la doc, consultes  notemment les classes Filter et dérivées

extrait de la doc : http://htmlparser.sourceforge.net/javadoc/org/htmlparser/filters/package-summary.html


These filters can be combined to yield powerful extraction capabilities.
For example, to get a list of links where the contents is an image, you could use:
NodeList list = new NodeList ();
NodeFilter filter =
new AndFilter (
new TagNameFilter ("A"),
new HasChildFilter (
new TagNameFilter ("IMG")));
for (NodeIterator e = parser.elements (); e.hasMoreNodes (); )
e.nextNode ().collectInto (list, filter);
0
jeanphi6 Messages postés 33 Date d'inscription samedi 2 avril 2005 Statut Membre Dernière intervention 24 juillet 2008
23 mai 2007 à 14:07
Merci bien pour tes infos AlexN, mais la solution HTMLParser a vite été écartée. J'ai réussi à obtenir ce que je voulais avec des regexp, donc niquel !
0
Rejoignez-nous