Файл, вероятно, закодирован как UTF-16.
>>> s = '"Vend, 21 sept, 2018","43326370894332743328177832888443325333815370","NX","651-2141652-1309NON666-3778692-2229581-300-6525622-9439NON581-998-8765827-3937STOPNON653-2541Toronto","RoyRoyHoudeOuelletFecteauRenaudBergeronLeclercBadeaux","Louise-AndréeAndréRichardAlexandraPaulineElianeCharles-EugèneGuyJacqueline","Vendredi, 21 septembre, 2018","","","3","37089","","100","","204-7584","MIller ","claudia","8:30 pt ne s\'est pas présenté (gastro) veut un autre rdv","370892192018","581-309-1309660-3064fille254-6560cel650-4556"'
>>> buf = io.BytesIO(s.decode('utf-8').encode('utf-16'))
>>> next(csv.reader(buf))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
_csv.Error: line contains NULL byte
Python2 Модуль CSV не обрабатывает UTF-16, как и пакет unicodecsv . Однако мы можем изменить unicode_csv_reader из примеров в документах :
import codecs
import csv
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')
with codecs.open('french2.csv', 'rU', encoding='utf-16') as f:
for row in unicode_csv_reader(f):
for cell in row:
print cell
Код производит этот вывод (одна ячейка печатается на строку только для отображения акцентированных символов):
Vend, 21 sept, 2018
43326370894332743328177832888443325333815370
NX
651-2141652-1309NON666-3778692-2229581-300-6525622-9439NON581-998-8765827-3937STOPNON653-2541Toronto
RoyRoyHoudeOuelletFecteauRenaudBergeronLeclercBadeaux
Louise-AndréeAndréRichardAlexandraPaulineElianeCharles-EugèneGuyJacqueline
Vendredi, 21 septembre, 2018
3
37089
100
204-7584
MIller
claudia
8:30 pt ne s'est pas présenté (gastro) veut un autre rdv
370892192018
581-309-1309660-3064fille254-6560cel650-4556
Ничего из этого не потребуется в Python3, вы можете просто сделать:
with open(myfile, 'r', newline='', encoding='utf-16') as f:
reader = csv.reader(f)
for row in reader:
...
Обзор
Идентификация кодировки
Угадывание неизвестной кодировки является проблемой без общее решение. В этом случае мы знаем, что закодированный текст содержит нулевые байты и что удаление нулевых байтов оставляет шестнадцатеричный escape, где мы ожидаем увидеть акцентированный европейский символ, но европейские символы без акцента остаются неизменными. Этого достаточно, чтобы предположить, что файл может быть закодирован как UTF-16; Для символов в диапазоне ASCII кодировка UTF-16 эффективно добавляет или добавляет нулевой байт к символу ASCII.
>>> u = u'André'
>>> s = u.encode('utf-16-le')
>>> s
'A\x00n\x00d\x00r\x00\xe9\x00'
Кодировка UTF-16 может быть с прямым или прямым порядком байтов; порядковый номер определяет, предшествует или следует ли нулевой байт символ ASCII. Байты могут включать в себя метку порядка байтов (BOM), которая указывает порядковый номер; в этом случае кодировка может быть указана как UTF-16 и Python выберет правильную кодировку. В отсутствие спецификации, utf-16-le или utf-16-be должны быть указаны явно.
Символ (('\ uffd') является символом замены Юникода и используется для отображения символов которые не могут быть отображены в выбранной кодировке (при условии, что аргумент errors
для str.encode
имеет значение «заменить», явно или неявно)
>>> print s
Andr�
Чтение модуля csv csv
Python 2 делает не справляется с кодировками не-ASCII. Чтобы обойти его ограничения, код выше
- декодирует содержимое файла с utf-16 в unicode
- перекодирует как utf-8 (чтобы избежать нулевых байтов)
- декодирует содержимое каждой ячейки из utf-8 в Unicode
После того, как содержимое было возвращено в программу как Unicode, оно может быть обработано без проблем, пока не будет закодировано для записи в файл или печать.
В Python 3 обработка текста, не относящегося к ASCII, намного проще: этот код сделает всю работу:
with open('french.csv', newline='', encoding='utf-16') as f:
reader = csv.reader(f)
for row in f:
print(row)