Comment gérer les caractères non ascii de CSV lors de l'utilisation de json.loads en Python ?


dwstein

J'ai regardé quelques réponses, y compris celle-ci, mais aucune ne semble répondre à ma question.

Voici quelques exemples de lignes de CSV :

_id category
ObjectId(56266da778d34fdc048b470b)  [{"group":"Home","id":"53cea0be763f4a6f4a8b459e","name":"Cleaning Services","name_singular":"Cleaning Service"}]
ObjectId(56266e0c78d34f22058b46de)  [{"group":"Local","id":"5637a1b178d34f20158b464f","name":"Balloon Dí©cor","name_singular":"Balloon Dí©cor"}]

Voici mon code :

import csv
import sys

from sys import argv
import json


def ReadCSV(csvfile):
with open('newCSVFile.csv','wb') as g:
    filewriter = csv.writer(g) #, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL)

    with open(csvfile, 'rb') as f:
        reader = csv.reader(f) # ceate reader object
        next(reader) # skip first row

        for row in reader: #go trhough all the rows
            listForExport = [] #initialize list that will have two items: id and list of categories

            # ID section
            vendorId = str(row[0]) #pull the raw vendor id out of the first column of the csv
            vendorId = vendorId[9:33] # slice to remove objectdId lable and parenthases
            listForExport.append(vendorId) #add evendor ID to first item in list


            # categories section
            tempCatList = []  #temporarly list of categories for scond item in listForExport

            #this is line 41 where the error stems
            categories = json.loads(row[1]) #create's a dict with the categoreis from a given row

            for names in categories:  # loop through the categorie names using the key 'name'

                print names['name']

Voici ce que j'obtiens :

Cleaning Services
Traceback (most recent call last):
  File "csvtesting.py", line 57, in <module>
    ReadCSV(csvfile)
  File "csvtesting.py", line 41, in ReadCSV
    categories = json.loads(row[1]) #create's a dict with the categoreis from a given row
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 338, in loads
return _default_decoder.decode(s)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 366, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 382, in raw_decode
    obj, end = self.scan_once(s, idx)
UnicodeDecodeError: 'utf8' codec can't decode bytes in position 9-10: invalid continuation byte

Ainsi, le code extrait la première catégorie Cleaning Services, mais échoue lorsque nous arrivons aux caractères non ascii.

Comment puis-je gérer cela? Je suis heureux de simplement supprimer tous les éléments non ASCII.

Serge Ballesta

Lorsque vous ouvrez le fichier csv d'entrée en rbmode, je suppose que vous utilisez une version Python2.x. La bonne nouvelle est que vous n'avez aucun problème dans la partie csv car le lecteur csv lira les octets simples sans essayer de les interpréter. Mais le jsonmodule insistera pour décoder le texte en unicode et utilisera par défaut utf8. Comme votre fichier d'entrée n'est pas codé en utf8, il s'étouffe et génère une erreur UnicodeDecodeError.

Latin1 a une propriété intéressante : la valeur unicode de n'importe quel octet n'est que la valeur de l'octet, vous êtes donc sûr de décoder n'importe quoi - si cela a du sens, cela dépend du fait que l'encodage réel est Latin1...

Donc tu peux juste faire :

categories = json.loads(row[1], encoding="Latin1")

Alternativement, si vous souhaitez ignorer les caractères non ascii, vous pouvez d'abord convertir la chaîne d'octets en Unicode en ignorant les erreurs et ensuite seulement charger le json :

categories = json.loads(row[1].decode(errors='ignore))     # ignore all non ascii characters

Articles connexes


Python: supprimer les caractères non ascii de csv

Dutta J'ai un fichier csv seulement 4 des 4000 enregistrements ont des caractères non-ASCII. Par example ['com.manager', '2016012300', '16.1.23', 'en', 'kinzie', '2015-04-11T17:36:23Z', '1428773783781', '2016-03-11T09:53:45Z', 'df', '5', "\xa5\x06`'", '\xc0\x0