Didacticiel :
Parser des fichiers HTML en Python

Ze amazing HTML cat (CC-BY Tomomi)

I can haz HTML (CC-BY Tomomi)

Langage : Python
Bibliothèques : bioservices, HTMLParser, re (partiellement)
Niveau : débutant-intermédiaire

Dans un article précédent, je vous ai présenté le module bioservices en Python. Au cours de mon travail j'ai été amenée à récupérer des informations sur les termes Gene Ontology, et notamment sur les relations entre différents termes. Cependant, les formats de fichiers récupérés sont différents en fonction des données qu'ils renferment. Dans cet article, je vais vous présenter comment récupérer dans un format facile à lire les données dans un fichier au format HTML à partir de la bibliothèque standard HTMLParser.

Récupérer les termes GO au format HTML

Dans un premier temps, nous allons utiliser le module bioservices pour récupérer les données sur le terme GO:0003824, qui correspond à l'activité catalytique. Le format demandé est le format 'mini'.

Parser le fichier HTML récupéré

La question que l'on se pose maintenant est quelle sera la bibliothèque Python à utiliser pour parser le fichier récupéré. Dans la bibliothèque standard il existe un module permettant de découper le format HTML selon les balises et les attributs, voyons comment nous récupérons les données de notre activité catalytique.

Dans ce script, je crée la classe BaseParser qui hérite de la classe HTMLParser (du module du même nom). Puis je surcharge les méthodes handle_starttag, handle_endtag et handle_data.

La méthode handle_starttag gère les ouvertures de balises (ou tag) tag ainsi que leurs attributs (comme l'attribut href de la balise <a>) attrs.

La méthode handle_endtag gère les fermetures de balises tag.

La méthode handle_data gère les données data contenues entre les balises d'ouverture et de fermeture.

Récupérer uniquement les fils de GO:0003824

Maintenant que l'on voit mieux comment fonctionne le module HTMLParser, nous allons pouvoir surcharger les méthodes à notre convenance afin de ne récupérer que les données du tableau des fils.

Pour cela nous définissions 3 variables booléennes : in_td, in_h2 et todo.

Si on rencontre un tag d'ouverture h2, alors la variable in_h2 vaut True. Si on rencontre un tag de fermeture h2, alors la variable in_h2 vaut False.

Si, pendant que in_h2 vaut True, les données valent "Children", alors la variable todo vaut True.

Si on rencontre un tag d'ouverture td, alors la variable in_td vaut True. Si on rencontre un tag de fermeture td, alors la variable in_td vaut False.

Lorsque l'on observe les données, si les variables in_td et todo valent toutes les deux True, alors on affiche les données contenues entre les balises d'ouverture et de fermeture de td.

Pour chaque données lue, on supprime le retour à la ligne (\n) et on supprime l'espace en début de chaîne avec le module de manipulation d'expression régulière re.

 Conclusion

En conclusion je dirai qu'il n'est pas toujours nécessaire de chercher de gros modules très complets et complexes pour traiter certains formats de fichiers, dans cet exemple vous pouvez constater que la bibliothèque standard de Python peut amplement suffire.

La raison principale pour laquelle je me suis penchée sur cette solution réside dans le fait que l'on ne peut pas toujours installer des mille et des cents de modules ou de programmes dans un environnement de travail professionnel. J'ai d'abord préféré chercher dans les modules de base avant de demander à ce que l'on m'installe un module plus complet et complexe.


Merci à Wocka, Yoann M. et ZaZo0o pour leur relecture et leurs commentaires.

  • À propos de
  • Issue d'une licence de biologie cellulaire et physiopathologie et d'un master de bioinformatique, je m'intéresse tout particulièrement au monde de la recherche et au domaine de la santé. J'ai travaillé dans l'unité 946 de l'INSERM, dirigée par Florence Demenais, où mon travail principal a été l'étude et la recherche de bases de données et d'outils d'intérêt majeur pour l'axe de recherche dans lequel j'étais impliquée. J'ai aussi travaillé à l'Institut Pasteur où j'ai été recrutée en tant qu'ingénieure bioinformaticienne dans le cadre du LabEx Milieu Intérieur et où ma mission principale a été de mettre en place une base de données pour la gestion de nos échantillons biologiques. Mes centres d'intérêt en bioinformatique sont : la mise en application de méthodes dans les domaines de la génomique, de la protéomique et les interactions gène-gène protéine-protéine pouvant nous apporter des informations sur leurs influences dans les maladies. Je travaille actuellement au service informatique de l'IBENS où j'ai été recrutée en qualité de développeuse d'applications !

4 commentaires sur “Parser des fichiers HTML en Python

  1. Hello,

    Tout d'abord merci pour l'article qui est très clair sur la marche à suivre pour utiliser HTMLParser.
    Par contre, j'ai quelques critiques à émettre.

    2 améliorations possibles sur le code écrit :
    - supprimer le exit() à la fin, il est inutile.
    - Pourquoi laisser les variables 'qg' et 'term' en globales ? Elles ont tout à fait leur place dans le main.
    C'est beaucoup plus propre et ca sera beaucoup plus facile de généraliser le script plus tard. 😉

    Enfin, j'ai beaucoup tiqué sur la conclusion qui est en partie fausse et en partie de mauvaise foi. Je m'explique :
    Ce que tu dis (sur le fait d'installer pleins de paquets) est vrai pour pas mal de langages (C++ par exemple) mais c'est en grande partie faux pour python.
    Python a un formidable outil de gestion de modules nommé 'pip' (qui est d'ailleurs standard maintenant dans la 3.4). Couplé facultativement avec un virtualenv,
    tu peux installer toi-même tes modules dans ton HOME sans rien demander à personne (avec l'option --user). Pip gère toutes les dépendances du modules et t'auras toujours la dernière version (contrairement à un apt-get ou yum. D'ailleurs il ne faudrait jamais gérer ses modules python avec ces installeurs).
    Donc, la majorité du temps, tu pourras toujours installer mille et cents modules dans ton environnement de travail professionnel sans ne rien casser ni demander à quelqu'un. C'est, ce que je trouve, une véritable force de Python.
    La où je trouve qu'il y a un peu de mauvaise foi, c'est lorsque tu dis "qu'il n'est pas nécessaire de chercher de gros modules très complets et complexes [...]" or tu utilises le module bioservices qui est une véritable usine 🙂 (11 dépendances d'après pip).
    D'ailleurs, dans ces dépendances, il y a "BeautifulSoup" qui est un très bon parser de HTML. Pourquoi ne pas l'avoir utiliser ?

    • Bonjour et merci pour votre retour.

      Alors, pour commencer, il est vrai que je ne l'ai pas précisé dans l'article, mais dans mon unité, sur une vingtaine de personnes, nous sommes 2 à coder en Python. Donc, installer VirtualEnv pour 2 personnes, et qui n'ont aucune formation dessus, je n'en vois pas trop l'intérêt dans l'immédiat, il est possible de s'en passer.
      De plus, nous avons des HOME très restreint en taille, ce qui fait que nous sommes très vite limité, donc VirtualEnv nous bloquerait rapidement pour ne serait-ce qu'un petit projet 🙂 !

      Pour BeautifulSoup, j'avoue que je l'ignorais, merci de m'en informer, je ne l'ai pas vu passer dans la liste des dépendances, pip gérant l'installation comme un grand, dépendances comprises, je n'ai pas prêté grande attention lorsque j'avais testé Bioservices sur une machine virtuelle 🙂 ! Ce qui explique pourquoi je ne l'ai pas utilisé. En revanche, je l'ai découvert après en voulant manipuler des données retournées dans une classe de BeautifulSoup (après avoir cherché à comprendre la classe en question).

      Pour finir, l'objectif de ce billet était de présenter HTMLParser, je l'ai fait en utilisant des données retournées grâce à Bioservices, tout comme j'aurais pu le faire avec une page de La Poste 🙂 !

      Donc, pour la mauvaise foi, un peu mais pas trop 🙂 !

      Bonne journée et encore merci pour votre retour.

      • On est d'accord qu'on peut très bien se passer de l'utilisation de virtualenv. Ca apporte juste une surcouche pour gérer différentes versions de modules.
        Par contre, rien n'empêche d'installer des modules localement via pip ailleurs que dans le HOME 😉

  2. HTMLParser est intéressant.

    Mais il y a en effet BeautifulSoup et aussi lxml surtout combiné avec html5lib. Par exemple

    from bs4 import BeautifulSoup
    htmlfile = urllib2.urlopen(uri)
    soup = BeautifulSoup(htmlfile, "html5lib")
    list = soup.find(class_='toto')

    ou bien

    from lxml.html import html5parser
    HTMLNS = "http://www.w3.org/1999/xhtml"
    parsed_html = html5parser.parse(uri)
    title = parsed_html.xpath('//h:title', namespaces={'h': HTMLNS})[0].text

Laisser un commentaire