INF8007 — Langages de script
Transcription
INF8007 — Langages de script
Introspection HTML Arbres XML INF8007 — Langages de script Introspection et parsage Michel Desmarais Génie informatique et génie logiciel École Polytechnique de Montréal Hiver, 2017 (30 janvier 2017) INF8007 — Langages de script — Introspection et parsage 1/20 Introspection HTML Arbres XML Introspection et parsage 1 L’introspection 2 Parseur HTML 3 Utilitaire pour arborescences XML INF8007 — Langages de script — Introspection et parsage 2/20 Introspection HTML Arbres XML Visibilité des attributs d’un objet Les bases de l’introspection Les attributs d’un objet sont nommés On peut obtenir une référence à l’attribut à partir du nom Permet un très haut niveau de dynamisme Affichage de l’API d’un objet Aiguillage (dispatching) basé sur des mots-clés dont certaines librairies font usage unittest utilise la nomenclature test <nom méthode> INF8007 — Langages de script — Introspection et parsage 3/20 Introspection HTML Arbres XML La fonction getattr > > > li = [ ] > > > dir ( li ) [ ' __add__ ' , ' __class__ ' , ... ' __str__ ' , ' append ' , ' count ' , ... ] > > > getattr ( li , ' append ') < built - in method append of list object at 0x6c2ab8 > > > > callable ( getattr ( li , ' append ') ) True > > > callable ( getattr ( li , ' __doc__ ') ) False > > > f = getattr ( li , ' append ') >>> f(2) > > > li [2] INF8007 — Langages de script — Introspection et parsage 4/20 Introspection HTML Arbres XML Utilisation de l’introspection Un exemple d’utilisation de getattr() pour l’aiguillage consiste à définir des méthodes qui suivent une nomenclature. Par exemple : Une classe générique est créée, foo, et comporte une méthode de défaut pour imprimer print default handler() On dérive une classe de foo, la classe bar, qui comporte des méthodes nommées selon la méthode de défaut On suit la nomenclature : print <nom> On définit un mécanisme pour associer un appel à la méthode spécifique si elle existe, sinon on appelle la méthode de défaut du parent. Quelques détails sont donnés dans le transparents suivant et la librairie SGML démontre une utilisation réaliste de ce mécanisme. INF8007 — Langages de script — Introspection et parsage 5/20 Introspection HTML Arbres XML L’instrospetion à l’oeuvre >>> ... >>> ... >>> >>> >>> class foo ( object ) : def p r i n t _ d e f a u l t _ h a n d l e r ( self ) : print ' foobar ' class bar ( foo ) : def print_abc ( self ) : print ' abc ' foo_inst = foo ( ) bar_inst = bar ( ) f = getattr ( foo_inst , ' print_abc ' , foo_inst . p r i n t _ d e f a u l t _ h a n d l e r ) >>> f() foobar > > > f = getattr ( bar_inst , ' print_abc ' , foo_inst . p r i n t _ d e f a u l t _ h a n d l e r ) >>> f() abc >>> INF8007 — Langages de script — Introspection et parsage 6/20 Introspection HTML Arbres XML Introspection et parsage 1 L’introspection 2 Parseur HTML 3 Utilitaire pour arborescences XML INF8007 — Langages de script — Introspection et parsage 7/20 Introspection HTML Arbres XML Le parsage Dans leur grand classique “Structure and interpretation of computer languages”, Sussman et Abelson soutiennent que tout programme de moindre envergure doit créer ses propres abstractions linguistiques. Fichiers de configuration Règles (ex. règles d’affaires ; règles de composition d’images) Traitement de la langue naturelle INF8007 — Langages de script — Introspection et parsage 8/20 Introspection HTML Arbres XML Parseur HTML de html.parser HTML est un langage de balises issus de SGML HTML n’a cependant pas la même exigence de rigueur qu’un langage SGML “normal” XML est aussi un dérivé de SGML XML sert toutefois à la définition d’autres langages, tout comme SGML Le parseur html.parser définit des méthodes selon le type de balises trouvé INF8007 — Langages de script — Introspection et parsage 9/20 Introspection HTML Arbres XML ExtracteurLiens La gestion du début d’une balise normale est faite par handle starttag Exemple avec un programme qui extrait les URL : class ExtracteurLiens ( html . parser . HTMLParser ) : def __init__ ( self ) : # constructeur html . parser . HTMLParser . __init__ ( self ) self . links = [ ] # liste des liens def handle_starttag ( self , tag , attrs ) : if tag = = 'a ' : for attr in attrs : if attr [ 0 ] = = " href " : self . links . append ( attr [ 1 ] ) INF8007 — Langages de script — Introspection et parsage 10/20 Introspection HTML Arbres XML ExtracteurLiens La méthode handle starttag sera appelée dès qu’une balise HTML normale <A ...> sera rencontrée. Il s’agit alors de vérifier si le nom de la balise (dans tag) est bien celui désiré INF8007 — Langages de script — Introspection et parsage 11/20 Introspection HTML Arbres XML Les données entre les balises Il y a d’autres types de handler selon le type de balises (commentaires, déclarations SGML, les caractères spéciaux, ou autres). On peut récupérer les données entre une balise comme : <P> Le texte d’un paragraphe </P> avec la méthode handle data def handle_data ( self , data ) : print ( ' Données : ' , data ) INF8007 — Langages de script — Introspection et parsage 12/20 Introspection HTML Arbres XML Utilisation with open ( ' fichier . html ' , ' rb ') as f : text = f . read ( ) parseur = ExtracteurLiens ( ) parseur . feed ( str ( text ) ) try : parseur . close ( ) # Termine la lecture except html . parser . HTMLParseError as e : print ( html . parser . HTMLParseError ) print ( getattr (e , ' msg ') ) print ( ' Ligne : ' + str ( getattr (e , ' lineno ') ) ) links = parseur . get_links ( ) # retourne self . links print ( ' Liens trouvés : ') print ( links ) INF8007 — Langages de script — Introspection et parsage 13/20 Introspection HTML Arbres XML Introspection et parsage 1 L’introspection 2 Parseur HTML 3 Utilitaire pour arborescences XML INF8007 — Langages de script — Introspection et parsage 14/20 Introspection HTML Arbres XML Utilitaire pour structure XML Les structures XML sont très utilisées et des utilitaires existent en Python pour les modèles DOM et SAX Pour une utilisation simple, comme la gestion d’un fichier de configuration, xml.etree.ElementTree est fort pratique : http://docs.python.org/library/xml.etree. elementtree.html INF8007 — Langages de script — Introspection et parsage 15/20 Introspection HTML Arbres XML Exemple > > > from slideshow import document > > > print document < slideshow > < title > Demo slideshow < / title > < slide > < title > Slide title < / title > < point > This is a demo < / point > < point > Of a program for processing slides < / point > < / slide > < slide > < title > Another demo slide < / title > < point > It is important < / point > < point > To have more than < / point > < point > one slide < / point > < / slide > < / slideshow > INF8007 — Langages de script — Introspection et parsage 16/20 Introspection HTML Arbres XML Exemple Extraction Extractions des noeuds point sous les noeuds slide : > > > from xml . etree . ElementTree import ElementTree > > > e = fromstring ( slideshow . document ) > > > for i in ( e . findall ( ' slide ') ) : ... for j in i . findall ( ' point ') : ... print ' point : % s ' % tostring ( j ) ... point : < point > This is a demo < / point > point : < point > Of a program for processing slides < / poi point : < point > It is important < / point > point : < point > To have more than < / point > point : < point > one slide < / point > INF8007 — Langages de script — Introspection et parsage 17/20 Introspection HTML Arbres XML Exemple Texte d’un noeud Extraction du texte des noeuds point > > > for i in ( e . findall ( ' slide ') ) : ... for j in i . findall ( ' point ') : ... print ' point : % s ' % j . text ... point : This is a demo point : Of a program for processing slides point : It is important point : To have more than point : one slide INF8007 — Langages de script — Introspection et parsage 18/20 Introspection HTML Arbres XML Manipulation de l’arbre etree Les paquetages TreeBuilder et XMLTreeBuilder permettent de créer des structures d’arbre En combinant XMLTreeBuilder avec une classe comme TreeBuilder, on peut notamment gérer des structures sur mesure ou qui ne respectent pas la syntaxe utile pour extraire des éléments d’un fichier HTML qui ne ferme pas les balises ! write permet d’écrire la structure XML dans un fichier et ElementTree.tostring() écrit dans une “string” INF8007 — Langages de script — Introspection et parsage 19/20 Introspection HTML Arbres XML Références Voir la documentation : http: //docs.python.org/py3k/library/html.parser.html http://docs.python.org/py3k/library/xml.etree. elementtree.html INF8007 — Langages de script — Introspection et parsage 20/20