• Keine Ergebnisse gefunden

Exemple 6 : Création d’un fichier HTML et stocker les résultats

3.11. Encodage et décodage des textes en python

150 Python gère plusieurs types d'encodage de texte. Cependant utf-8 est le langage universel, il est donc conseillé de l'utiliser. Sous windows, on utilise fréquemment Latin_1 pour les caractères accentués. Pour voir la liste des encodage sous python, on fait:

import encodings

for code in sorted(set(encodings.aliases.aliases.values())):

print(code)

Et comme certains de ces encodages ont plusieurs alias, on pourrait donc en compter plus:

print(len(encodings.aliases.aliases.keys()))

Pour avoir des informations sur l'encoding du système utilisé, on fait :

import sys

print(sys.getdefaultencoding()) # Pour voir le codage par défaut de python

print(sys.stdin.encoding) # l'encode des inputs (fichiers utilisés par système d'exploitation)

print(sys.stdout.encoding) # l'encodage des outputs (fichiers crées par le système)

print(sys.getfilesystemencoding()) # Encodage du système d'exploitation. Sous windows, cela renvoie 'mbcs'

Et Pour fixer l'encodage dans le programme, on ajoute en début de programme la ligne suivante (avec #):

# -*- coding : Nomencodage -*

où Nomencodage doit être remplacé par le type d'encoage utf8 ou Latin_1 . Exemples :

# -*- coding : utf-8 -*

# -*- coding : Latin-1 -*

En Python 3, le codage utf-8 est automatique. Toutes les chaînes sont par défaut de type 'str' Il faut savoir que pour toute opération de manipulation de fichier (reading, writing), deux opérations sont souvent nécessaires: encoding et decoding. On utilise l'encoding lorsque l'on a obtenu un fichier de résultats et qu'on veut l'enregistrer sur le disque. On utilise le décoding, lorsqu'on a un fichier input et qu'on souhaite faire d'autres opérations. Nous allons donc détailler ci-dessous ces deux opérations.

3.11.1. Décodage de texte

Pour décoder un texte reçu, on utilise la fonction decode(). La syntaxe du décoage est la suivante:

monTexte.decode('nomencoding','errorstype')

151 Où monTexte est le texte à décoder ; nomEncoding est le nom de l’encodage dans lequel se trouve déjà le texte. Le paramètre errorstype prend par défaut la valeur 'strict' qui signifie que l’encodage doit soulever unqiement des erreurs liés aux type Unicode. Les autres valeurs sont 'ignore', 'replace', 'xmlcharrefreplace', 'backslashreplace'.

Exemple1 : Obtenir une chaîne 'unicode' depuis une chaîne 'str' encodée en utf8 : Soit le texte suivant:

une_chaine = 'Chaîne' # cette valeur est déja encodée en UTF8, donc la chaine est en UTF8

type(une_chaine) # donne <type 'str'>

une_chaine = une_chaine.decode('utf8') # met le texte en unicode.

Attention l'attribut decode n'est disponible que quand le texte en question est déjà encodé.

type(une_chaine) # donne <type 'unicode'>

Exemple 2

mystr = "this is string example....wow!!!";

mystr1 = mystr1.encode('ascii','strict'); # on va d'abord l'encoder en byte avant de le décoder.

On a:

mystr2=mystr1.decode('ascii','strict')

print ("Encoded String: " + str(mystr1) ) # renvoie: b'this is string example....wow!!!'

print ("Decoded String: " + mystr2) # this is string example....wow!!!

Noter aussi qu'on peut utiliser le module codecs pour effectuer le décodage d'un fichier. Ou plutôt ouvrir un fichier dans le codec indiqué. Exemple:

import codecs# le module codecs est installé par défaut avec python.

f = codecs.open("file.txt", "r", "utf-8") # ouvre le fichier en mode read "r" initialisé encodé en utf-8.

Il existe diverses autres fonctions associées à codecs. Consulter par exemple la page https://docs.python.org/2/library/codecs.html

3.11.2. Encodage de texte

L'encodage est la démarche inverse du décodage qui consiste à partir d'un texte avec un codage donné pour le mettre sous un autre codage. Sa syntaxe est la même que pour le décodage en remplaçant simplement decode par encode. Exemple:

mystring = "this is string example....wow!!!"; # un texte de codage par défaut str.

152 mystring=mystring.encode('cp037','strict')

print (mystring) # donne:

b'\xa3\x88\x89\xa2@\x89\xa2@\xa2\xa3\x99\x89\x95\x87@\x85\xa7\x81\x94\x97\x93\x85KKKK

\xa6\x96\xa6ZZZ'

Ainsi pour décoder ce texte et le mettre sous codage str, on fait:

mystring=mystring.decode('cp037','strict') print (mystring)

NB: un texte ne peut avoir avoir à la fois l'attribut encode et decode à la fois. C'est soit l'un ou l'autre.

3.11.3. Peut-on détecter l'encodage d'un fichier texte ?

Dans l'optique d'une manipulation de texte, la seule difficulté pour décoder un texte est de savoir quelle est le codage d'origine. Malheureusement, il n'y aucune règle qui permet de déterminer avec précision l'encodage d'un texte (à moins que celui qui a été crée le fichier indique). Par exemple, pour les pages html ou xml, le type d'encoding est souvent fournit en en-tête (ex: charset="utf-8"). C'est ce que l'on doit utiliser pour décoder le texte avant de l'utiliser le coding d'un texte. Il faut donc faire extrêment attention lorsqu'on veut décoder un fichier. Il faut s'assurer que le codec en question est bien le bon.

Pour détecter l'encodage d'un fichier texte, il n'y a pas de régles pour déterminer l'encodage d'un fichier. D'abord, une manière plus simple serait de copier un caractère dans le texte et de rechercher dans les bases de normes comme utf-8, ISO, etc... Sinon on peut faire quelques remarques comme suit (à utiliser avec précautions):

Normalement, il y a au début du fichier un BOM (byte order mark), c'est à dire une séquence d'octets:

- UTF8 : 3 premiers octets = EF BB BF

- UTF-16/UCS-2 (big-endian) : 2 premiers octets = FE FF - UTF-16/UCS-2 (little-endian) : 2 premiers octets = FF FE - ASCII/AINSI : pas de BOM, directement le contenu.

En UTF-8, les caractères sont généralement codés sur 1, 2 ou 3 octets (cela peut être plus, mais c'est rare). Ce codage respecte les règles suivantes :

codage sur 1 octet : 0xxxxxxx

codage sur 2 octets : 110xxxxx 10xxxxxx

codage sur 3 octets : 1110xxxx 10xxxxxx 10xxxxxx (représentation en binaire des octets. "x"

signifiant valeur quelconque)

153 Connaissant tous ces éléments, il suffit de parcourir le fichier pour voir si les règles sont respectées. Par exemple si un octet commence par 110????? Alors l'octet suivant commence par 10??????. A la première violation des règles, on peut arrêter de parcourir le fichier et supposer que ce n'est pas de l'UTF-8.

Pour l'ASCII c'est facile : toutes les valeurs sont inferieure à 128, c'est à dire que tous les octets sont de la forme 0xxxxxxx. D'ailleurs les formats UTF-8, ANSI et ISO sont compatibles avec l'ASCII. (ANSI : organisme de standardisation americain ; ISO : organisme de standardisation international).

3.12. Présentation du module URLLIB pour gestion des urls