IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

encodage d'un fichier csv


Sujet :

Python

  1. #1
    Membre averti
    Inscrit en
    Mars 2009
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 30
    Par défaut encodage d'un fichier csv
    salut,
    comment peut-on connaitre l'encodage utilisé dans un fichier donnée format csv. lorsque je lis le fichier avec la fonction open, des caractère comme par exemple le caractère (—) s'affiche comme ça (�) malgré que j'ai utilisé le codage utf8 le problème reste toujours. merci d'avance.

  2. #2
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 307
    Par défaut
    Salut,

    Où as-tu utilisé l'encodage utf-8 ? Dans l'entête de ton script Python, à l'écriture du fichier csv, à la lecture ?

    Est-ce qu'il se lit correctement dans un bloc-note ?

  3. #3
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Avec Python 2.7, le module csv ne supporte que l'utf-8.

    Le problème est que:
    - la bonne pratique est de travailler en ram avec les chaines en unicode
    - pour des échanges avec Excel, il faut utiliser l'encodage Windows cp1252 pour les fichiers csv sur disque.

    Il faut donc envelopper le traitement csv par des conversions d'encodage. Je le fais en utilisant un fichier en mémoire cStringIO.StringIO() comme intermédiaire.

    Dans le sens lecture:
    1- lecture du fichier disque avec le module codecs (cp1252=>unicode), et écriture du fichier en mémoire (unicode=>utf-8)
    2- lecture par csv à partir du fichier en mémoire (utf-8=>utf-8)
    3- conversion des chaines en unicode (utf-8=>unicode)

    On adopte le même principe dans le sens écriture csv (unicode=>utf-8=>utf-8=>cp1252).

    Ça a l'air compliqué comme ça, mais une fois mis au point, c'est très rapide et ça marche très bien.

  4. #4
    Membre averti
    Inscrit en
    Mars 2009
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 30
    Par défaut encodage
    salut tout le monde
    oui, j'ai utilisé le codage utf-8 et le encodage de Windows cp1252 mais le problème reste toujours. sachant que le fichier csv je l'ai pas créé en utilisant la programmation en python, c'est un fichier qui existe déja.

  5. #5
    Membre chevronné
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    290
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 290
    Par défaut
    Citation Envoyé par phpines Voir le message
    j'ai utilisé le codage utf-8 et le encodage de Windows cp1252
    Les problématiques d'encodage ne sont visiblement pas votre tasse de thé. Vous devriez poster votre code, ou en tout cas la partie qui s'occupe du décodage csv.

  6. #6
    Membre averti
    Inscrit en
    Mars 2009
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 30
    Par défaut encodage
    voici le code: comment faire ça en utilisant cStringIO?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    import csv
    import codecs
     
    class Profiltableur(csv.Dialect):
        delimiter = ','
        quotechar = '"'
        doublequote = True
        skipinitialspace = False
        lineterminator = '\r\n'
        quoting = csv.QUOTE_MINIMAL
     
     
    source  = codecs.open("fichin.txt", "rb", 'cp1252')
    destination = codecs.open("fichout.csv", "wb", "utf-8")
     
    c = csv.writer(destination, dialect=Profiltableur )
     
    entete = source.readline().rstrip('\n\r').split("\t")
    col1 = entete.index("col1")
    col2 = entete.index("col2")
    text = entete.index("text")
    col4 = entete.index("col4")
     
    # Ecrit l'en-tete
    destination.write("col1,col2,col3,col4\r\n")
     
    for ligne in source:
        # Extraction des donnees de la ligne separees par tabulation
        donnees = ligne.rstrip('\r\n').split("\t")
        donnees[text]=donnees[text].decode("cp1252")
        donnees[text]=donnees[text].encode("utf8")
        c.writerow((donnees[col1], donnees[col2], donnees[text], donnees[col4))
     
    destination.close()
    source .close()

  7. #7
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Voilà un code qui:

    - lit un fichier csv encodé 'cp1252' et le convertit en une liste de listes encodée unicode

    - écrit un fichier csv encodé 'cp1252' à partir d'une liste de listes encodée unicode

    Si le fichier csv a un autre encodage, il suffit de le signaler dans l'appel des fonctions.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    from __future__ import division
    # Python 2.7
     
    import csv, codecs, cStringIO
     
    #############################################################################
    class Profiltableur(csv.Dialect):
        """Profil de lecture/écriture de fichiers CSV avec des tableurs"""
        delimiter = ';'
        quotechar = '"'
        doublequote = True
        skipinitialspace = False
        lineterminator = '\r\n'
        quoting = csv.QUOTE_MINIMAL
     
    # enregistrement du profil pour lecture/écriture de fichier csv du disque
    csv.register_dialect('profiltableur', Profiltableur())
     
    #############################################################################
    def lirecsv(fichier, codisk='cp1252'):
        """lit le fichier CSV encodé codisk, et le retourne comme une liste de 
           listes encodée unicode
        """
     
        # lit le fichier sur disque et le met dans un fichier en ram
        fs = cStringIO.StringIO()
        with codecs.open(fichier, 'r', codisk) as f:
            for ligne in f:
                fs.write(ligne.encode('utf-8'))
     
        #lit les lignes csv du fichier en ram et convertit en liste de listes
        tableau = []
        fs.seek(0) # remet le curseur au début du fichier en ram
        for ligne in csv.reader(fs, dialect='profiltableur'):
            tableau.append([]) # ajouter une ligne vide
            for elem in ligne:
                tableau[-1].append(elem.decode('utf-8'))
        return tableau
     
    #############################################################################
    def ecrirecsv(tableau, fichier, codisk='cp1252'):
        """enregistre la liste de listes (tableau) unicode dans le fichier csv 
           avec l'encodage codisk
        """
     
        # ouverture du fichier en ram
        fs = cStringIO.StringIO()
        # écriture de la liste convertie en format csv, dans le fichier en ram
        c = csv.writer(fs, dialect='profiltableur')
        for liste in tableau:
            ligne = []
            for elem in liste:
                ligne.append(elem.encode('utf-8'))
            # conversion de la ligne en liste => ligne en chaine format csv
            c.writerow(ligne)
     
        # écriture sur disque du fichier en ram, avec correction d'encodage
        fs.seek(0) # remet le curseur au début du fichier en ram
        with codecs.open(fichier, 'w', codisk) as f:
            for ligne in fs:
                f.write(ligne.decode('utf-8'))
    Exemple d'utilisation:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    fichier = "fichier.csv"
    tableau = lirecsv(fichier)
     
    for ligne in tableau:
        for elem in ligne:
            print elem,
        print    
     
    fichier2 = "fichier2.csv"
    ecrirecsv(tableau, fichier2)
    Ces codes sont simplifés sur un point: les tableaux en mémoire ne comportent que des chaines unicode.

    - en lecture, les nombres (int, long, float) sont intégrés comme des chaines. Si on veut les transformer en nombres et qu'on sait dans quelle colonne ils sont, on les convertit facilement. Sinon, il faut les trouver avec des expressions régulières. C'est apparemment ce que fait Excel, puisqu'il arrive à trouver que les codes postaux sont des entiers. Attention pour les flottants: Excel y met une virgule et non un point décimal. Il faut donc remplacer la virgule par un point avant la conversion par float.

    - en écriture, les nombres doivent être convertis avant en chaines unicodes, et les flottants doivent avoir une virgule décimale pour être reconnus comme flottants par Excel.

    Ok?

  8. #8
    Membre averti
    Inscrit en
    Mars 2009
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 30
    Par défaut
    merci beaucoup tyrtamos.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème encodage fichier CSV
    Par Idleman dans le forum ASP.NET
    Réponses: 4
    Dernier message: 15/10/2012, 07h37
  2. Réponses: 22
    Dernier message: 20/07/2010, 15h43
  3. [phpMyAdmin] Encodage et importation / exportation fichier CSV
    Par mikael2235 dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 3
    Dernier message: 01/06/2010, 22h02
  4. Problème d'encodage de fichier (.csv-->.sql, .sql-->.csv)
    Par croustibapt dans le forum Entrée/Sortie
    Réponses: 5
    Dernier message: 09/07/2009, 10h17
  5. Réponses: 4
    Dernier message: 29/02/2008, 11h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo