8.2. Présentation de sgmllib.py

Le traitement du HTML est divisé en trois étapes : diviser le HTML en éléments, modifier les éléments et reconstruire le HTML à partir des éléments. La première étape est réalisée par sgmllib.py, qui fait partie de la bibliothèque standard de Python.

La clé de la compréhension de ce chapitre est de réaliser que le HTML n’est pas seulement du texte, c’est du texte structuré. La structure est dérivée de la séquence plus ou moins hiérarchique de balises de début et de fin. Habituellement, on ne travaille pas de cette manière sur du HTML, on travaille textuellement dans un éditeur de texte ou visuellement dans un navigateur ou un éditeur de pages web. sgmllib.py présente le HTML de manière structurelle.

sgmllib.py contient une classe principale : SGMLParser. SGMLParser analyse le HTML et le décompose en éléments utiles, comme des balises de début et de fin. Dès qu’il parvient à extraire des données un élément utile, il appelle une de ses propres méthodes en fonction de l’élément trouvé. Pour utiliser l’analyseur, on dérive une classe de SGMLParser et on redéfinit ces méthodes. C’est ce que j’entendais par présentation du HTML de manière structurelle : la structure du code HTML détermine la séquence d’appels de méthodes et les arguments passés à chaque méthode.

SGMLParser décompose le HTML en 8 sortes de données et appelle une méthode différente pour chacune d’entre elles :

Balise de début
Une balise HTML qui ouvre un bloc, comme <html>, <head>, <body> ou <pre>, ou une balise autonome comme <br> ou <img>. Lorsqu’il trouve une balise de début tagname, SGMLParser cherche une méthode nommée start_tagname ou do_tagname. Par exemple, lorsqu’il trouve une balise <pre>, il cherche une méthode nommée start_pre ou do_pre. S’il la trouve, SGMLParser l’appelle avec une liste des attributs de la balise en paramètre, sinon il appelle unknown_starttag avec le nom de la balise et la liste de ses attributs en paramètre.
Balise de fin
Une balise HTML qui ferme un bloc, comme </html>, </head>, </body> ou </pre>. Lorsqu’il trouve une balise de fin, SGMLParser cherche une méthode nommée end_tagname. S’il la trouve, SGMLParser appelle cette méthode, sinon il appelle unknown_endtag avec le nom de la balise.
Référence de caractère
Un caractère référencé par son équivalent décimal ou hexadécimal, comme &#160;. Lorsqu’il en trouve une, SGMLParser appelle handle_charref avec le texte de l’équivalent décimal ou hexadécimal.
Référence d’entité
Une entité HTML, comme &copy;. Lorsqu’il en trouve une, SGMLParser appelle handle_entityref avec le nom de l’entité HTML.
Commentaire
Un commentaire HTML, encadré par <!-- ... -->. Lorsqu’il en trouve un, SGMLParser appelle handle_comment avec le corps du commentaire.
Instruction de traitement
Une instruction de traitement HTML, encadrée par <? ... >. Lorsqu’il en trouve une, SGMLParser appelle handle_pi avec le corps de l’instruction.
Déclaration
Une déclaration HTML, comme un DOCTYPE, encadrée par <! ... >. Lorsqu’il en trouve une, SGMLParser appelle handle_decl avec le corps de la déclaration
Données texte
Un bloc de texte. Tout ce qui n’entre dans aucune des 7 catégories précédentes. Lorsqu’il en trouve un, SGMLParser appelle handle_data avec le texte.
Important
Python 2.0 avait un bogue qui empêchait SGMLParser de reconnaître les déclarations (handle_decl n’était jamais appelé), ce qui veut dire que les DOCTYPEs étaient ignorés silencieusement. Ce bogue est corrigé dans Python 2.1.

sgmllib.py est accompagné d'une suite de tests pour illustrer cela. Si on exécute sgmllib.py en lui passant le nom d’un fichier HTML en argument de ligne de commande, il affichera les balises et les autres éléments au fur et à mesure qu’il analyse le fichier. Il fait cela en dérivant une classe de SGMLParser et en définissant des méthodes comme unknown_starttag, unknown_endtag, handle_data et autres qui ne font qu’afficher leur argument.

ASTUCE
Dans l’IDE ActivePython sous Windows, vous pouvez spécifier des arguments de ligne de commande dans la boîte de dialogue «Run script». Séparez les différents arguments par des espaces.

Exemple 8.4. Exemple de test de sgmllib.py

Voici un extrait de la table des matières de la version HTML de ce livre. Bien sûr, les chemins peuvent être différents. Si vous n'avez pas téléchargé la version HTML du livre, vous pouvez le faire à l'adresse suivante : https://book.diveintopython.org/.

c:\python23\lib> type "c:\downloads\diveintopython\html\toc\index.html"

<!DOCTYPE html
  PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
   
      <title>Dive Into Python</title>
      <link rel="stylesheet" href="diveintopython.css" type="text/css">

... nous coupons la suite pour rester bref ...

En l’utilisant avec la suite de tests de sgmllib.py, on obtient la sortie suivante :

c:\python23\lib> python sgmllib.py "c:\downloads\diveintopython\html\toc\index.html"
data: '\n\n'
start tag: <html lang="en" >
data: '\n   '
start tag: <head>
data: '\n      '
start tag: <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" >
data: '\n   \n      '
start tag: <title>
data: 'Dive Into Python'
end tag: </title>
data: '\n      '
start tag: <link rel="stylesheet" href="diveintopython.css" type="text/css" >
data: '\n      '

... nous coupons la suite pour rester bref ...

Voici le plan du reste de ce chapitre :

En cours de route, vous apprendrez également locals, globals et le formatage de chaînes à l'aide de dictionnaire.