Чтение UTF-8 с BOM с использованием модуля Python CSV вызывает нежелательные дополнительные символы [дубликаты]

Я пытаюсь прочитать файл CSV с помощью Python со следующим кодом:

with open("example.txt") as f:
   c = csv.reader(f)
   for row in c:
      print row

Мой example.txt имеет только следующее содержимое:

Hello world!

Для файлов в кодировке UTF-8 или ANSI это дает мне ожидаемый результат:

> ["Hello world!"]

Но если я сохраню файл как UTF-8 со спецификацией, я получу следующий вывод:

> ["\xef\xbb\xbfHello world!"]

Поскольку у меня нет никакого контроля над тем, какие файлы пользователь будет использовать в качестве входных данных, я хотел бы, чтобы это работало и со спецификацией. Как я могу решить эту проблему? Есть ли что-то, что мне нужно сделать, чтобы убедиться, что это работает и для других кодировок?


person Anders    schedule 18.11.2015    source источник
comment
NB: какое бы решение вы ни использовали, важно использовать utf-8-sig для декодирования.   -  person ekhumoro    schedule 18.11.2015
comment
import csv,csvkit,codecs,unicodecsv with open("example.txt",'r') as f: c = csv.reader(f) for row in c: print [unicode(s, "utf-8") for s in row] with open("example.txt",'r') as f: c = unicodecsv.reader(f) for row in c: print row with open("example.txt",'r') as f: c = csvkit.reader(f) for row in c: print row все печатает [u'\ufeffHello world!'], поэтому я думаю, что это не дубликат - первая попытка использует stackoverflow.com/questions/17245415/   -  person SIslam    schedule 18.11.2015
comment
@ekhumoro: Дубликат - это пограничная линия ... Другой вопрос касается данных UTF-8, а этот конкретно касается спецификации в файле utf8. На другой странице говорится (только в одном ответе) о спецификации для файлов UTF-16. Ваш комментарий действительно отвечает на этот вопрос, но ИМХО он заслуживает того, чтобы быть ответом на не дублирующийся вопрос :-)   -  person Serge Ballesta    schedule 18.11.2015
comment
@SergeBallesta. Пожалуйста, прочитайте вопрос внимательнее (особенно последний абзац) - речь идет не только о подписи utf-8. Кроме того, ответ с наибольшим количеством голосов в дубликате специально использует utf-8-sig; но некоторые другие ответы этого не делают, поэтому я добавил здесь комментарий.   -  person ekhumoro    schedule 18.11.2015


Ответы (1)


Вы можете использовать модуль unicodecsv Python следующим образом:

import unicodecsv

with open('input.csv', 'rb') as f_input:
    csv_reader = unicodecsv.reader(f_input, encoding='utf-8-sig')
    print list(csv_reader)

Итак, для входного файла, содержащего следующее в UTF-8 со спецификацией:

c1,c2,c3,c4,c5,c6,c7,c8
1,2,3,4,5,6,7,8

Он будет отображать следующее:

[[u'c1', u'c2', u'c3', u'c4', u'c5', u'c6', u'c7', u'c8'], [u'1', u'2', u'3', u'4', u'5', u'6', u'7', u'8']]

Модуль unicodecsv можно установить с помощью pip следующим образом:

pip install unicodecsv
person Martin Evans    schedule 18.11.2015
comment
а как же \ufeff? разве это не бесполезно? - person SIslam; 18.11.2015
comment
Действительно, я бы вставил неправильную кодировку, как указано, следует использовать utf-8-sig. - person Martin Evans; 18.11.2015