Я пытаюсь прочитать CSV-файл с акцентированными символами с помощью Python (только французские и / или испанские символы). Основываясь на документации Python 2.5 для csvreader ( http://docs.python.org/library/csv.html ), я придумал следующий код для чтения файла CSV, поскольку csvreader поддерживает только ASCII.
def unicode_csv_reader(unicode_csv_data, dialect=csv.excel, **kwargs):
# csv.py doesn't do Unicode; encode temporarily as UTF-8:
csv_reader = csv.reader(utf_8_encoder(unicode_csv_data),
dialect=dialect, **kwargs)
for row in csv_reader:
# decode UTF-8 back to Unicode, cell by cell:
yield [unicode(cell, 'utf-8') for cell in row]
def utf_8_encoder(unicode_csv_data):
for line in unicode_csv_data:
yield line.encode('utf-8')
filename = 'output.csv'
reader = unicode_csv_reader(open(filename))
try:
products = []
for field1, field2, field3 in reader:
...
Ниже приведен отрывок из CSV-файла, который я пытаюсь прочитать:
0665000FS10120684,SD1200IS,Appareil photo numérique PowerShot de 10 Mpx de Canon avec trépied (SD1200IS) - Bleu
0665000FS10120689,SD1200IS,Appareil photo numérique PowerShot de 10 Mpx de Canon avec trépied (SD1200IS) - Gris
0665000FS10120687,SD1200IS,Appareil photo numérique PowerShot de 10 Mpx de Canon avec trépied (SD1200IS) - Vert
...
Несмотря на то, что я пытаюсь кодировать / декодировать в UTF-8, я все равно получаю следующее исключение:
Traceback (most recent call last):
File ".\Test.py", line 53, in <module>
for field1, field2, field3 in reader:
File ".\Test.py", line 40, in unicode_csv_reader
for row in csv_reader:
File ".\Test.py", line 46, in utf_8_encoder
yield line.encode('utf-8', 'ignore')
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 68: ordinal not in range(128)
Как это исправить?
python
utf-8
csv
character-encoding
Мартин
источник
источник
Ответы:
.encode
Метод будет применяться к строке Unicode , чтобы сделать байт-строку; но вместо этого вы вызываете его в байтовой строке ... неправильно! Посмотрите наcodecs
модуль в стандартной библиотеке и,codecs.open
в частности, на лучшие общие решения для чтения текстовых файлов в кодировке UTF-8. Однако,csv
в частности , для модуля вам необходимо передать данные utf-8, и это то, что вы уже получаете, поэтому ваш код может быть намного проще:import csv def unicode_csv_reader(utf8_data, dialect=csv.excel, **kwargs): csv_reader = csv.reader(utf8_data, dialect=dialect, **kwargs) for row in csv_reader: yield [unicode(cell, 'utf-8') for cell in row] filename = 'da.csv' reader = unicode_csv_reader(open(filename)) for field1, field2, field3 in reader: print field1, field2, field3
PS: если окажется, что ваши входные данные НЕ в utf-8, а, например, в ISO-8859-1, тогда вам понадобится «перекодирование» (если вы хотите использовать utf-8 на
csv
уровне модуля) , формыline.decode('whateverweirdcodec').encode('utf-8')
- но, вероятно, вы можете просто использовать имя вашей существующей кодировки вyield
строке в моем коде выше, вместо того'utf-8'
, какcsv
на самом деле будет хорошо с кодированными строками байтов ISO-8859- *.источник
Python 2.X
Существует библиотека unicode-csv, которая должна решить ваши проблемы, с дополнительным преимуществом, заключающимся в том, что не нужно писать какой-либо новый код, связанный с csv.
Вот пример из их readme:
>>> import unicodecsv >>> from cStringIO import StringIO >>> f = StringIO() >>> w = unicodecsv.writer(f, encoding='utf-8') >>> w.writerow((u'é', u'ñ')) >>> f.seek(0) >>> r = unicodecsv.reader(f, encoding='utf-8') >>> row = r.next() >>> print row[0], row[1] é ñ
Python 3.X
В python 3 это сразу поддерживается встроенным
csv
модулем. См. Этот пример:import csv with open('some.csv', newline='', encoding='utf-8') as f: reader = csv.reader(f) for row in reader: print(row)
источник
Если вы хотите прочитать CSV-файл с кодировкой utf-8, минималистичный подход, который я рекомендую вам, - использовать что-то вроде этого:
with open(file_name, encoding="utf8") as csv_file:
С этим утверждением вы можете позже использовать для работы программу чтения CSV.
источник
encoding
inopen
open('file.csv', 'r', encoding="ISO8859")
Также ознакомьтесь с ответом в этом сообщении: https://stackoverflow.com/a/9347871/1338557
Предлагается использовать библиотеку ucsv.py. Краткая и простая замена CSV, написанная для решения проблемы кодирования (utf-8) для Python 2.7. Также обеспечивает поддержку csv.DictReader
Изменить : добавление образца кода, который я использовал:
import ucsv as csv #Read CSV file containing the right tags to produce fileObj = open('awol_title_strings.csv', 'rb') dictReader = csv.DictReader(fileObj, fieldnames = ['titles', 'tags'], delimiter = ',', quotechar = '"') #Build a dictionary from the CSV file-> {<string>:<tags to produce>} titleStringsDict = dict() for row in dictReader: titleStringsDict.update({unicode(row['titles']):unicode(row['tags'])})
источник
Использование,
codecs.open
как предложил Алекс Мартелли, оказалось для меня полезным.import codecs delimiter = ';' reader = codecs.open("your_filename.csv", 'r', encoding='utf-8') for line in reader: row = line.split(delimiter) # do something with your row ...
источник
csv
модуль, но не используете его.Ссылка на страницу справки такая же для python 2.6, и, насколько мне известно, в модуле csv с версии 2.5 не было никаких изменений (кроме исправлений ошибок). Вот код, который работает без какого-либо кодирования / декодирования (файл da.csv содержит те же данные, что и данные переменных ). Я предполагаю, что ваш файл должен читаться правильно без каких-либо преобразований.
test.py:
## -*- coding: utf-8 -*- # # NOTE: this first line is important for the version b) read from a string(unicode) variable # import csv data = \ """0665000FS10120684,SD1200IS,Appareil photo numérique PowerShot de 10 Mpx de Canon avec trépied (SD1200IS) - Bleu 0665000FS10120689,SD1200IS,Appareil photo numérique PowerShot de 10 Mpx de Canon avec trépied (SD1200IS) - Gris 0665000FS10120687,SD1200IS,Appareil photo numérique PowerShot de 10 Mpx de Canon avec trépied (SD1200IS) - Vert""" # a) read from a file print 'reading from a file:' for (f1, f2, f3) in csv.reader(open('da.csv'), dialect=csv.excel): print (f1, f2, f3) # b) read from a string(unicode) variable print 'reading from a list of strings:' reader = csv.reader(data.split('\n'), dialect=csv.excel) for (f1, f2, f3) in reader: print (f1, f2, f3)
da.csv:
0665000FS10120684,SD1200IS,Appareil photo numérique PowerShot de 10 Mpx de Canon avec trépied (SD1200IS) - Bleu 0665000FS10120689,SD1200IS,Appareil photo numérique PowerShot de 10 Mpx de Canon avec trépied (SD1200IS) - Gris 0665000FS10120687,SD1200IS,Appareil photo numérique PowerShot de 10 Mpx de Canon avec trépied (SD1200IS) - Vert
источник
delimiter=','
вместоdialect=csv.excel
.Стоит отметить, что если у вас ничего не получилось, возможно, вы забыли сбежать со своего пути.
Например, такой код:
f = open("C:\Some\Path\To\file.csv")
Приведет к ошибке:
Чтобы исправить, просто выполните:
f = open("C:\\Some\\Path\\To\\file.csv")
источник
Глядя на
Latin-1
таблицу юникода , я вижу код символа00E9
« СТРОЧНАЯ ЛАТИНСКАЯ БУКВА E С ОСТРЫМ ». Это символ с ударением в ваших данных выборки. Простой тестPython
показывает, чтоUTF-8
кодировка этого символа отличается отUTF-16
кодировки Unicode (почти ).>>> u'\u00e9' u'\xe9' >>> u'\u00e9'.encode('utf-8') '\xc3\xa9' >>>
Я предлагаю вам попробовать
encode("UTF-8")
данные в Юникоде перед вызовом специальногоunicode_csv_reader()
. Простое чтение данных из файла может скрыть кодировку, поэтому проверьте фактические значения символов.источник
Была такая же проблема на другом сервере, но я понял, что локали перепутались.
export LC_ALL="en_US.UTF-8"
исправил проблему
источник