Как изменить кодировку csv файла на utf 8 python

Обновлено: 06.07.2024

Ниже приведен экстракт CSV-файла, который я пытаюсь прочитать:

хотя я пытаюсь кодировать / декодировать в UTF-8, я все еще получение следующего исключения:

The .encode метод применяется к строке Юникода, чтобы сделать байт-строку; но вы вызываете его на байт-строку вместо этого. неправильно! Посмотрите на codecs модуль в стандартной библиотеке и codecs.open в частности, для улучшения общих решений для чтения текстовых файлов в кодировке UTF-8. Однако, для csv модуль в частности, вам нужно передать данные utf-8, и это то, что вы уже получаете, поэтому ваш код может быть намного проще:

PS: Если это оказывается, что ваши входные данные находятся не в utf-8, а, например, в ISO-8859-1, тогда вам нужно "перекодирование" (если вы заинтересованы в использовании utf-8 в csv уровень модуля), формы line.decode('whateverweirdcodec').encode('utf-8') -- но, вероятно, вы можете просто использовать имя существующей кодировке в yield строка в моем коде выше, вместо 'utf-8' , а csv на самом деле будет просто отлично с ISO-8859-* закодированные bytestrings.

Python 2.X

есть unicode-csv библиотека, которая должна решить ваши проблемы, с дополнительным преимуществом не навинга для написания любого нового кода, связанного с csv.

вот пример из их readme:

Python 3.X

в python 3 это поддерживается из коробки встроенным csv модуль. См. этот пример:

используя codecs.open как предложил Алекс Мартелли, оказалось полезным для меня.

ссылка на страницу справки одинакова для python 2.6 и, насколько я знаю, не было никаких изменений в модуле csv с 2.5 (кроме исправлений ошибок). Вот код, который просто работает без кодирования / декодирования (файл da.csv содержит те же данные, что и переменная данные). Я предполагаю, что ваш файл должен быть правильно прочитан без каких-либо преобразований.

test.py:

да.csv:

смотреть на!--9--> Latin-1 таблица Юникод, Я вижу код символа 00E9 "ЛАТИНСКАЯ СТРОЧНАЯ БУКВА Е С ОСТРЫМ". Это символ с ударением в образце данных. Простой тест в Python видно, что UTF-8 кодировка для этого символа отличается от Юникода (почти UTF-16 ) кодирование.

Я предлагаю вам попробовать encode("UTF-8") данные unicode перед вызовом специального unicode_csv_reader() . Простое чтение данных из файла может скрыть кодировка, поэтому проверьте фактические значения символов.

Если вы хотите прочитать CSV-файл с кодировкой utf-8, минималистичный подход, который я рекомендую вам использовать что-то вроде этого:

С этим утверждением вы можете использовать позже читатель CSV для работы.

Всем привет, столкнулся с записью кириллицы в CSV - файл. есть такой код:

5ad72f911334c025099332.jpg


В итоге, в файле получаю кракозябру:

Как правильно записать кириллицу?

Простой 9 комментариев

shpaker

shpaker

Странно. А если попробовать писать в кодировке cp1251?

crazyzubr

Смотря откуда вы берете данные в data. Из приведенного кода неясно

sim3x

Какой питон?
В какой кодировке исходный текст?
В какой требуется вставить в csv?
Принт пишет то что нужно до вставки в csv? sim3x,
Python 3.5.2
Данные зашиты хардкодом, UTF-8
Файл CSV создаётся при записи
Принт пишет то, что нужно Файл CSV - plain text файл, не надо открывать его в Ёкселе. Любой редактор, поддерживающий UTF-8. В Linux это любой, в винде - в поиск.

shpaker

AVKor, ну с чего это? LO, AOO, Excel нормально с CSV работают

A. Shpak, Ёксель научился нормально работать с кодировками?

Он перестал "умно" конвертировать данные из одного формата в другой, когда его об этом не просят?

И - ещё раз - зачем открывать текстовый файл в этом ПО, если для этого есть текстовые редакторы, которые не будут при этом заниматься подобной ерундой, а просто покажут файл так как есть?

Я пытаюсь перевести электронную таблицу Excel в CSV с помощью модулей Python xlrd и csv, но зацикливаюсь на вопросах кодирования. Xlrd производит вывод из Excel в Unicode, а для модуля CSV требуется UTF-8.

Мне показалось, что это не имеет ничего общего с модулем xlrd: все отлично работает, выводя на стандартный вывод или другие выходные данные, которые не требуют определенной кодировки.

Рабочий лист закодирован как UTF-16-LE в соответствии с book.encoding

Упрощенная версия того, что я делаю:

Это приводит к следующей ошибке, около 740 строк:

Похоже, что значение зацикливается на "516-777316" - текст на оригинальном листе Excel - "516-7773167" (с 7 на конце)

Я буду первым, кто признает, что у меня есть только смутное представление о том, как работает кодировка символов, поэтому большинство из того, что я пробовал до сих пор, - это разные неуклюжие изменения .encode и .decode в s.cell_value(row,col)

Если бы кто-то мог предложить решение, я был бы признателен, даже лучше, если бы вы предоставили объяснение того, что не работает и почему, чтобы я мог легче отлаживать эти проблемы самостоятельно в будущем.

EDIT:

Спасибо за комментарии.

Когда я использую this_row.append(s.cell(row,col)) (например, s.cell вместо s.cell_value), весь документ записывается без ошибок.

Вывод не особенно желателен ( text:u'516-7773167' ), но он позволяет избежать ошибки, даже если оскорбительные символы все еще находятся в выводе ,

Это заставляет меня думать, что в конце концов проблема может быть в xlrd.

4 ответа

Я ожидаю, что возвращаемое значение cell_value - это строка в кодировке Юникод, которая вызывает проблемы (пожалуйста, напечатайте ее type() , чтобы подтвердить это), и в этом случае вы сможете решить эту проблему, изменив эту строку:

Если cell_value возвращает несколько разных типов, то вам нужно кодировать, если и только если он возвращает строку Юникода; поэтому вы бы разбили эту строку на несколько строк:

Вы попросили объяснений, но некоторые явления необъяснимы без вашей помощи.

(A) Строки в файлах XLS, созданных в Excel 97 и более поздних версиях, кодируются в Latin1, если это возможно, в противном случае в UTF16LE. Каждая строка несет флаг, говорящий, который был использован. Ранее Excels кодирует строки в соответствии с «кодовой страницей» пользователя. В любом случае xlrd создает объекты в юникоде . Кодировка файла представляет интерес, только если файл XLS был создан сторонним программным обеспечением, которое либо пропускает кодовую страницу, либо лжет об этом. См. Раздел «Юникод» в начале документа xlrd.

(B) Необъяснимое явление:

вызывает следующую ошибку в Python 2.5, 2.6 и 3.1: TypeError: expected at most 2 arguments, got 3 - это примерно то, что я ожидал, учитывая документы на csv.writer; он ожидает файлоподобный объект, за которым следует либо (1) ничего (2) диалект или (3) один или несколько параметров форматирования. Вы дали ему диалект, а csv.writer не имеет аргумента кодировки, так что splat. Какую версию Python вы используете? Или вы не скопировали /вставили скрипт, который на самом деле выполняли?

(C) Необъяснимые явления, связанные с отслеживанием, и фактические оскорбительные данные:

В первую очередь, в строке кода, вызывающей нарушение, есть строка str (), которой нет в упрощенном сценарии. Разве вы не копировали /вставляли сценарий, который фактически выполняли? В любом случае, вы не должны использовать str в целом - вы не получите полную точность для ваших float; просто дайте модулю csv преобразовать их.

Во-вторых, вы говорите "" "Кажется, значение зацикливается на" 516-777316 "- текст на оригинальном листе Excel -" 516-7773167 "(с 7 на конце)" «» - трудно представить, как семерка теряется с конца. Я бы использовал что-то вроде этого, чтобы выяснить, какие именно проблемные данные были:

То, что% r избавляет вас от ввода cell_value=%s . repr(s.cell_value(row, col)) . repr () создает однозначное представление ваших данных. Узнать его. Используйте это.

Как вы пришли к "516-777316"?

В-четвертых, местоположение ошибки кажется движущейся целью - вы сказали в комментарии к одному из решений: «Ошибка на bcw.writerow». А?

(E) "" ". s.cell (row, col)) (egscell вместо s.cell_value) всего документ записывается без ошибок. Вывод не особенно желателен (текст: u'516-7773167 ') "" "

Это происходит потому, что писатель csv вызывает метод __str__ вашего объекта Cell, и в результате получается <type>:<repr(value)> , который может быть полезен для отладки, но, как вы говорите, не очень хорош в вашем CSV-файле.

(F) Решение Алекса Мартелли великолепно тем, что оно помогло вам. Однако вы должны прочитать раздел о классе Cell в xlrd docs: типы ячеек: текст, число, логическое значение, дата, ошибка, пустое и пустое значение. Если у вас есть даты, вы захотите отформатировать их как даты, а не числа, поэтому вы не можете использовать isinstance () (и, возможно, вы не захотите накладные расходы на вызов функции) . это то, что Cell.ctype и атрибут Sheet.cell_type() и Sheet.row_types() методы для.

(G) UTF8 не является Unicode. UTF16LE не является Unicode. UTF16 не является Unicode . и идея, что отдельные строки будут тратить 2 байта каждая в спецификации UTF16, слишкомдаже нелепо, чтобы рассудить было нелепо: -)

(H) Дополнительная литература (кроме xlrd документов):

Похоже, у тебя 2 проблемы.

В этой ячейке что-то напортачило - я думаю, что «7» должно быть закодировано как u'x37, так как оно находится в диапазоне ASCII.

Похоже, есть две возможности. Во-первых, возможно, вы неправильно открыли выходной файл:

Если это не проблема, тогда другой вариант для вас - использовать codecs.EncodedFile (file, input [, output [, errors]]) в качестве оболочки для вывода вашего .csv:

Это позволит вам иметь фильтр файловых объектов от входящего UTF16 до UTF8. Хотя оба они технически являются «юникодом», способ их кодирования сильно отличается.

может решить проблему за вас, если я правильно понял проблему и предположил, что при записи в файл возникла ошибка.

Программисты часто сталкиваются с задачей обработки больших объемов структурированных данных. Python имеет встроенную библиотеку CSV, с помощью которой программист может работать со специальными CSV файлами. Это своего рода электронные таблицы.

Что такое файлы CSV

Файл CSV – это особый вид файла, который позволяет структурировать большие объемы данных.

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

Пример CSV файла, где в качестве разделителя используется запятая:

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

Вместо запятой можно использовать любой другой разделитель, поэтому при чтении CSV файла нужно заранее знать, какой символ используется.

Важно помнить, что CSV – это обычный текстовый файл, который не поддерживает символы в кодировках, отличающихся от ASCII или Unicode.

Библиотека CSV

Эта основная библиотека для работы с CSV файлами в Python.

Библиотека csv является встроенной, поэтому её не нужно скачивать, достаточно использовать обычный импорт:

Чтение из файлов (парсинг)

Для того чтобы прочитать данные из файла, программист должен создать объект reader:

reader имеет метод __next__() , то есть является итерируемым объектом, поэтому чтение из файла происходит следующим образом:

Предположим, что у нас есть CSV файл, который содержит следующую информацию:

Тогда, если открыть этот файл в нашей программе, то будут получены следующие результаты:

Использование конструкции with…as позволяет программисту быть уверенным, что файл будет закрыт, даже если при выполнении кода произойдет какая-то ошибка.

Библиотека CSV позволяет работать с файлами, как со словарями, для этого нужно создать объект DictReader. Обращаться к элементам можно по имени столбцов, а не с помощью индексов. Для того, чтобы исходная программа делала аналогичный вывод, её следует изменить следующим образом:

Обращаться к элементам по названию столбца более удобно, кроме того, это упрощает понимание кода.

Обратите внимание, что в цикл for при первой итерации будет записан в row не шапка таблицы, а первая её строка. Поэтому при выводе количества строк переменную count увеличили на 1.

Дополнительные параметры объекта DictReader

DictReader имеет параметры:

Например, если бы в classmates.csv не было бы первой строки с заголовками, то можно было бы его открыть следующим образом:

Также можно использовать метод __next__() для получения следующей строки. Этот метод делает объект reader итерируемым. То есть он вызывается при каждой итерации и возвращает следующую строку. Этот метод и используется при каждой итерации в цикле for для получения очередной строки.

Запись в файлы

Для записи информации в CSV файл необходимо создать объект writer:

Для записи в файл данных используется метод writerow(), который имеет следующий синтаксис:

Код программы для записи в CSV файл выглядит так:

Обратите внимание, что при записи использовался, lineterminator="\r" . Это разделитель между строками таблицы, по умолчанию он "\r\n" .

После выполнения программы в файле CSV будет следующий текст:

В качестве параметра метод writerow() принимает список, элементы которого будут записаны в строку через символ-разделитель.

Запись в файл также может быть осуществлена с помощью объекта DictWriter. Важно помнить, что он требует явного указания параметра fieldnames. В качестве аргумента метода writerow используется словарь.

Код программы выглядит так:

Вывод в файл будет следующим:

Дополнительные параметры DictWriter

Объект writer также имеет атрибут dialect, который определяет, как будут форматироваться данные при записи в файл, про него будет описано ниже.

Кроме того, writer имеет методы:

writeheader был использован в предыдущем примере. Рассмотрим применение writerows :

Диалекты

Чтобы каждый раз не указывать формат входных и выходных данных, определенные параметры форматирования сгруппированы в диалекты (dialect). При создании объекта reader или writer программист может указать нужный ему диалект, кроме того, некоторые параметры диалекта можно переопределить вручную, также указав их при создании объекта.

Для создания диалекта используется команда:

Класс Dialect позволяет определить следующие атрибуты форматирования:

Читайте также: