Master 1 Plurital 2012
December 31 2012
Les pages ont été aspirées. Celles qui n'ont pas été aspirées ont renvoyé un code erreur, qui a été récupéré, afin d'étudier l'erreur et/ou de procéder avec le traitement uniquement des pages qui ont été correctement aspirées.
La prochaine étape est de vérifier l'encodage des pages aspirées, afin d'extraire le contenu textuel et de le convertir en utf-8. En bash, c'est la commande 'file -i' qui donne une indication de l'encodage utilisé en renvoyant une description du contenu. Elle examine le contenu du fichier, en particulier le type d'octets et la séquence d'octets utilisés pour afficher le texte. Elle n'est pas fiable à 100% mais elle peut donner une bonne indication.
En python il existe 'chardet', qui renvoie l'encodage du fichier donné, et le degré de certitude associé à cette détection d'encodage. Elle est plus intéressante que 'file' car elle donne une assurance qui n'est pas fournie par 'file'. Le résultat est renvoyé sous forme d'un dictionnaire :
Ce qui nous intéresse est l'encodage. Nous ne sommes pas obligées d'extraire l'encodage via un cut (comme nous avons fait pour le résultat de 'file') puisque les informations ici sont en forme de dictionnaire. Pour avoir seulement l'encodage, il suffit de spécifier que nous voulons les informations associées à l'entrée du dictionnaire qui s'appelle ['encoding']. Nous pouvons également extraire l'assurance en spécifiant ['confidence'] pour récupérer le degré de certitude (sur 1).
Pour tester 'chardet' avec toutes les URLs, l'extraction de l'encodage et le degré de certitude ont été intégrés au script; une autre colonne au tableau pour les afficher.
N.B. en écrivant l'encodage suivi par le chiffre entre parenthèses il faut être conscient du fait que le degré de certitude est de type float et non pas string. Il est d'abord nécessaire de préciser que nous voulons le chiffre en tant que string avant de les concaténer, ou sinon d'effectuer de mutliples 'prints', un pour chaque type d'objet à afficher.
Parfois ce chiffre peut contenir beaucoup de chiffres décimaux (il est type float). Il est possible de préciser que nous voulons seulement un certain nombre de chiffres après la virgule en utilisant 'round' qui prend en argument le nombre et le nombre de chiffres décimaux que nous voulons obtenir.
A première vue, chardet semble bien fonctionner. Il fournit un encodage (ou au moins une estimation éclairée de l'encodage) dans TOUS les cas, contrairement à "file" qui renvoie souvent la réponse "unknown 8-bit". En plus, le niveau de "confidence" est généralement entre 0.8 et 1. Il faut se méfier des encodages où 'chardet' est moins sûr - par exemple l'URL numéro 11, qui reçoit un niveau d'assurance de seulement 60%. En regardant dans le code source de la page, nous voyons qu'il n'existe même pas de balise 'meta charset' et l'encodage n'est indiqué nulle part. Donc nous ne pouvons même pas récupérer l'encodage de l'intérieur du fichier.
Curieusement, l'URL numéro 5 a été détecté comme de l'ISO-8859-2, qui est un encodage standard pour les langues de l'Europe Centrale (le polonais, le croate, le hongrois, le serbe etc.) Mais URL numéro 5 est écrite en anglais !!! En regardant dans le code source de la page, nous voyons que l'encodage du fichier est non pas de l'ISO-8859-2 mais de l'ISO-8859-1 :
Pourquoi chardet a-t-il reconnu l'encodage comme de l'ISO 8859-2 ? La réponse est que chardet ne peut pas reconnaître Latin-1. Il détecte seulement les encodages suivants :
ASCII, UTF-8, UTF-16 (2 variants), UTF-32 (4 variants)
Big5, GB2312, EUC-TW, HZ-GB-2312, ISO-2022-CN (Traditional and Simplified Chinese)
EUC-JP, SHIFT_JIS, ISO-2022-JP (Japanese)
EUC-KR, ISO-2022-KR (Korean)
KOI8-R, MacCyrillic, IBM855, IBM866, ISO-8859-5, windows-1251 (Cyrillic)
ISO-8859-2, windows-1250 (Hungarian)
ISO-8859-5, windows-1251 (Bulgarian)
windows-1252 (English)
ISO-8859-7, windows-1253 (Greek)
ISO-8859-8, windows-1255 (Visual and Logical Hebrew)
TIS-620 (Thai)
Incapable d'identifier l'encodage correct, chardet choisit l'encodage le plus proche.
En regardant quelques autres liens, il y a d'autres approximations. Quelques URLs en grec, encodées (selon le code source) en windows-1253 (qui n'est pas détecté non plus par chardet) sont détectées par chardet comme de l'ISO-8859-7. Quelques URLs en français, encodées (selon le code source) en ISO-8859-1 sont détectées par chardet comme du windows-1255.
En comparant ces résultats avec les résultats de 'file' (en bash), il est clair que les deux fonctions n'ont pas détecté l'encodage de la même manière :
Il est difficile de comparer les résultats à cause du mauvais fonctionnement de 'curl' sur un petit ordinateur avec une connexion internet peu rapide. Ceci explique le rouge dans le tableau ci-dessus (mais on nous assure que c'est simplement à cause de notre connexion d'Internet !). Donc on ne pourra pas comparer l'extraction de l'encodage directement dans les tableaux. Mais nous pouvons voir, par exemple, que l'URL numéro 5 a été détectée comme de l'ASCII.
Nous pouvons comparer 'file' et 'chardet' en testant 'file' dans le terminal sur les mêmes URLs :
Anglais Britannique numéro 5 :
Anglais Britannique numéro 11 :
Français numéro 30 :
Grec numéro 30 :
Alors, on abandonne ?
Ces "erreurs" sont-elles importantes ?
'Chardet' et 'file' n'ont pas détecté les encodages tels qu'ils étaient indiqués dans le code source de la page. Nous aurons besoin par la suite de convertir les contenus textuels en utf-8, donc connaître l'encodage est important. Mais il faudrait examiner les encodages plus en détail pour voir si la différence de détection est vraiment importante. Si, par exemple, le vrai encodage et l'encodage détecté se différencient uniquement par des caractères qui n'apparaissent pas dans le texte extrait, la conversion marchera malgré tout. Ce qui est important est que l'intersection entre le véritable encodage du fichier et l'encodage détecté soit suffisante pour afficher tous les caractères du contenu textuel du fichier en question.
Une solution pratique serait de répérer quand chardet détecte un certain encodage et de modifier l'encodage selon nos estimations afin d'obtenir un meilleur résultat. Par exemple, nous savons que chardet ne peut pas détecter Latin-1 et que presque systématiquement il détecte les textes en Latin-1 comme du Latin-2. Il serait possible d'ajouter une condition à notre script qui modifie les encodages détectés comme du Latin-2 en les réécrivant comme du Latin-1, puisqu'il y a très peu de chance que nos URLS soient écrites avec l'encodage pour l'hebreu. Ceci dit, ce n'est pas une solution idéale, puisqu'elle pourrait provoquer des problèmes SI l'encodage est véritablement Latin-2, ou également si l'encodage d'origine n'est pas spécifiquement Latin-1.
Il y a peu d'espoir, mais nous intégrons cette étape dans le script et en ajoutons une autre : le dump (plain text à partir de l'html) et la conversion en utf-8 si nécessaire.
Pour faire la conversion de l'html vers le texte brut, nous avons utilisé la fonction nltk.clean_html(), qui prend en argument une chaîne de caractères html et qui renvoie le texte brut. Contrairement à lynx, clean_html laisse vide les endroits qui étaient remplis par l'html, ce qui explique les grands vides dans le texte produit.
Le fichier résultant est ci-dessus et nous voyons que changer l'encodage entre ISO-8859-7 et windows-1253 ne modifie pas l'affichage du texte grec.
Pour faire la conversion en utf-8 nous utilisons les fonctions 'decode' et 'encode' de python. Ce premier décode le texte au format d'encodage de python, afin ensuite d'encoder au format d'encodage spécifié (ici c'est de l'utf-8).
Ce petit script effectue la conversion d'un fichier grec, dont l'encodage initial était de l'ISO-8859-7, en utf-8. Bien-sûr qu'il faudrait prendre en compte que cet encodage est l'encodage fourni par chardet - si chardet se trompe, la conversion ne se passera pas forcément bien. Avec ce fichier-là, la conversion se passe très bien et les caractères s'affichent correctement dans la version utf-8. En intégrant cette partie dans le script, toutes les pages aspirées semblent être bien converties en utf-8, avec affichage correct de tous les caractères.
Pour l'anglais, la conversion produit quelques caractères irréguliers - des caractères ASCII qui s'affichent mal :
” pour les guillemets doubles (de droite) (")
' pour un guillemet simple (')
’ pour un guillemet simple (')
& pour l'esperluette (&)
Ces caractères s'affichent mal dans le dump initial et le dump utf-8, ce qui suggère que cela ne vient pas de la conversion utf-8. De plus, la plupart de ces fichiers étaient déjà encodés en utf-8. Le problème vient peut-être du fait qu'il existe une confusion entre les apostophes et les guillemets - et souvent il n'y a pas de constance entre la sorte de ponctuation utilisée. Ce sont souvent ces caractères-là qui s'affichent mal lorsqu'il y a un problème d'encodage. Ici, c'est un problème d'affichage associé au texte brut (puisque les mêmes problèmes n'existent pas pour la page aspirée en html, où ces caractères-là sont interprétés par le navigateur).
Pour le français, comme prévu il y a des erreurs d'affichage pour les textes dont l'encodage a été mal détecté - une 'solution' pratique a été mise en oeuvre pour le changement de "Latin-1" à "Latin-2" mais non pas pour "windows-1255", "ISO-8859-7" et "IBM855" (!!!) Les caractères accentués pour ces textes-là ne s'affichent pas du tout correctement. Traiter ces encodages de la même manière est problématique parce qu'il existe des URLs grecques qui sont encodées en ISO-8859-7. Nous ne pouvons pas associer ISO-8859-7 a un autre encodage plus probable pour le français, parce que cela créerait des problèmes pour l'encodage du grec. De plus, ce n'est pas une solution pour traiter le problème en général - si éventuellement il y avait d'autres fichiers avec des URLs en d'autres langues, notre 'solution' pourrait entraîner des difficultés, et nous en rencontrerions sûrement d'autres.
Il est temps de trouver une autre solution pour mieux traiter cette étape : En attente de l'article suivant !