Overblog All blogs Top blogs Jobs, Education & Studies
Edit post Follow this blog Administration + Create my blog
MENU
L'Américanisation

Master 1 Plurital 2012

Advertising

Python : extraction du contenu textuel et encodage (2ème essai)

Suite aux problèmes rencontrés avec la détection de l'encodage avec chardet, nous avons cherché une autre solution.  Nous avons entendu parler de la bibliothèque 'BeautifulSoup', qui pourrait peut-être mieux détecter l'encodage.  C'est une bibliothèque pour analyser plus facilement les documents html en parcourant l'aborescence, qui donne la possibilité de récupérer le contenu des balises.

 

BeautifulSoup a beaucoup de fonctionnalités dont nous n'avons pas besoin.  Notre tâche est de simplement récupérer le contenu textuel du site.

 

Mais nous pouvons quand-même admirer quelques commandes de la bibliothèque qui pourraient être utiles.  Par exemple, la commande 'prettify()' permet de mieux présenter un document html mal présenté, en ajoutant de l'indentation et du formatage standard.

Advertising
Python : extraction du contenu textuel et encodage (2ème essai)
avant 'prettify'

avant 'prettify'

après 'prettify'

après 'prettify'

Advertising

Je l'accorde, le document html du départ n'était pas trop mal présenté et peut-être plus lisible que le fichier enjolivé, mais pour un autre document qui contient plus d'informations qu'un tableau contenant des lignes et des colonnes, ce serait un outil très utile, qui crée une représentation visuelle plus cohérente de l'arborescence.

 

Pour l'extraction du contenu textuel, leur site recommande d'utiliser soup.get_text() pour extraire juste le texte d'un document (où soup est l'objet qui contient le contenu en html). Pourtant le résultat est un mélange de html et de texte et je n'arrive pas à le faire fonctionner proprement. En tout cas, nltk.clean_html a bien fait le travail donc il n'y a pas de raison de changer cette étape pour le dump initial.

 

Pour l'encodage, BeautifulSoup nous semble intéressante, puisqu'elle fonctionne uniquement avec Unicode, et transforme les objets de sortie en UTF-8. Elle possède un détecteur d'encodage supérieur, et donc devrait avoir moins de problèmes avec l'encodage. Elle utilise la sous-bibliothèque UnicodeDammit, qui convertit du texte en UTF-8, et qui est particulièrement utile quand on ne connaît pas l'encodage du fichier.

 

La conversion se fait avec le code suivant (après le dump initial fait par nltk) :

 

Python : extraction du contenu textuel et encodage (2ème essai)

...sauf que le texte original était encodé en Latin-1 et non pas en Latin-2.  Comme avec chardet, l'encodage original a été mal détecté, ce qui pose un problème pour la conversion des caractères accentués. 

Comme indiqué dans la documentation, la détection d'encodage est nettement améliorée si on lui donne une liste d'encodages possibles (si un encodage est plus probable qu'un autre).

En testant avec quelques fichiers URL dont l'encodage est connu (dans le code source des pages), nous voyons que les résultats sont bien meilleurs (même si le bon encodage n'est pas le premier dans la liste) : 

La bonne conversion des fichiers en UTF-8
La bonne conversion des fichiers en UTF-8
La bonne conversion des fichiers en UTF-8
La bonne conversion des fichiers en UTF-8

La bonne conversion des fichiers en UTF-8

Advertising

Alors la solution serait de donner en argument l'encodage extrait du code source de la page.  Ce n'est pas une solution miracle, et peut-être pas une meilleure solution que 'decode' et 'encode' de python, mais il semble au moins être une bonne manière d'assurer la bonne conversion de nos fichiers.

 

Maintenant il faudrait extraire le charset du fichier html, en utilisant une expression régulière.  Les commandes Python ne fonctionnent pas comme ceux en Bash et, bien que ça soit possible d'imiter les tubes en Python, ça ne fait pas partie de son fonctionnement de base.  Donc l'extraction du charset se fera par le stockage de texte extrait (de plus en plus raffiné) dans des variables :

Python : extraction du contenu textuel et encodage (2ème essai)


La première expression régulière trouve toute occurrence d'une balise 'meta charset' et la stocke dans la variable 'encodage'.  Le résultat est une liste d'occurrences.  Normalement il devrait y avoir une seule occurrence d'une balise meta charset, mais il peut y en avoir plus (comme précédemment avec la page britannique numéro 5).  Pour accéder au texte stocké dans la variable, il faudrait spécifier un élément dans la liste.  Puisque la plupart des pages n'auront qu'une occurrence de la balise charset, on spécifie qu'on veut le premier élément.  Avec ce texte, on cherche une deuxième expression régulière qui extrait la partie "charset=..." jusqu'à la fin de la balise (plus précisement, jusqu'à la première occurrence d'un "\' ou un ">" qui peuvent indiquer la fermeture de la balise).  Un split sera effectué sur ce résultat, autour du séparateur "=".  La partie qui nous intéresse est le texte qui suit le signe égal, donc la dernière expression s'effectue sur le deuxième élément de la liste résultante et extrait tous les caractères alpha-numérique et des tirets de 6 - pourvu qu'il en existe - et s'arrête à la première occurrence d'un espace ou un guillemet après le charset indiqué.  Le script suivant montre ce filtrage pas par pas :

Python : extraction du contenu textuel et encodage (2ème essai)

Dans le cas où plusieurs charsets sont identifiés dans un seul fichier, ce script prendra le premier, en espérant qu'il est le bon !  Mais la page britannique numéro 5 ne contient pas de balise meta charset et donc provoque une erreur dans le terminal qui s'arrête le programme.  Ceci montre qu'il faudrait ajouter une condition avant l'extraction de sorte que le charset soit extrait seulement si la balise existe dans le fichier.

 

Maintenant nous pouvons passer aux étapes suivantes : si l'encodage est de l'utf-8, nous pouvons nettoyer le texte avec nltk.clean_html() et faire directement le dump en utf-8.  Si ce n'est pas de l'utf8, un dump initial avec nltk.clean_html() (dans l'encodage original) sera effectué avant de faire la conversion avec UnicodeDammit.  Si un encodage a été trouvé dans le fichier source, ceci aidera la conversion.  Sinon, UnicodeDammit tentera de convertir le fichier selon ses propres estimations (ce qui n'est pas toujours très fiable - comme on a vu). 

Le Script
Le Script
Le Script
Le Script
Le Script
Le Script
Le Script
Le Script
Le Script

Le Script

Les tableaux résultants

Les tableaux résultants

Share this post
Repost0
To be informed of the latest articles, subscribe:
Comment on this post