Как решить: импорт файла Python с .csv Dictreader не выполняется на неопределенном символе

Прежде всего, я нашел следующие, который в основном совпадает с моим вопросом, но он закрыт, и я не уверен, что понимаю причину закрытия по сравнению с содержанием сообщения. Я тоже не вижу рабочего ответа.

У меня более 20 входных файлов из 4 приложений. Все файлы экспортируются как файлы .csv. Первые 19 файлов работали (еще 4 были экспортированы из того же приложения), а затем я наткнулся на файл, который дает мне эту ошибку:

UnicodeDecodeError: 'charmap' codec can't decode byte 0x8f in position 5762: character maps to <undefined>

Если я посмотрел правильно, это & ​​lt ctrl & gt. В приведенном ниже коде есть соответствующие строки:

with open(file, newline = '') as f: 
    reader = csv.DictReader(f, dialect = 'excel')
    for line in reader:

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

Так что вопрос, вероятно, состоит из нескольких частей:
1) Есть ли способ указать csv.DictReader игнорировать неопределенные символы? (Подсказка для кодека: если я его не вижу, это не имеет для меня никакого значения.)

2) Если у меня есть «сумасшедшие» персонажи, что мне делать? Я рассматривал возможность открытия каждого ввода как двоичного файла, фильтрации оскорбительных шестнадцатеричных символов, записи файла обратно на диск, а затем открытия нового файла, но это похоже на большие накладные расходы для программы и даже больше для меня. Это также несколько заявлений JCL из 1977 года.

3) Как мне понять, что я получаю в качестве ввода, если он вылетает, пока я его читаю.

4) Я выбрал «диалект = 'excel'»; потому что многие входные данные представляют собой файлы Excel, которые можно загрузить из одного из исходных приложений. Из документации по dictreader у меня сложилось впечатление, что он просто определяет разделитель, символ кавычек и символы EOL, которые следует ожидать / использовать. Поэтому я не думаю, что это моя проблема, но я тоже новичок в Python, поэтому я не уверен на 100%.

Возможный дубликат: stackoverflow.com/questions/30750843/…

Greenstick 30.08.2018 01:09

Эта проблема часто возникает, когда среда считывает файлы в кодировке ASCII, когда они на самом деле являются UTF-8 (что кажется вероятным, поскольку в ваших CSV-файлах есть символы неанглийского языка). Попробуйте обновить код, указав кодировку текста: with open(file, newline = '', encoding = 'utf8') as f:

Greenstick 30.08.2018 01:12

К сожалению, это не сработало. Только что получил другое сообщение: UnicodeDecodeError: кодек utf-8 не может декодировать байт 0x96 в позиции 197: недопустимый начальный байт

Tim B 30.08.2018 01:36

Я вернулся к исходному файлу и открыл его в Excel. Я сделал «сохранить как» для типа .csv (не для Unicode). Он уже был настроен на этот формат файла, так что это отвечает, является ли он Unicode. Проблема в том, что данные поступают из инструмента обнаружения, который может извлекать данные с тысяч устройств по всему миру. Так что в исходном файле действительно могут быть странные вещи

Tim B 30.08.2018 03:34

Нашел ответ. Основываясь на отзывах, я решил посмотреть, есть ли другие кодеки, которые мне стоит попробовать. Просматривая документацию, я обнаружил, что в open errors есть параметр = 'strict'. На самом деле не было сказано, какие были другие варианты, но это привело к правильному поиску в Google. Этот поток является дубликатом, но не относится к теме, упомянутой выше. Правильный ответ - открыть файл с ошибкой = 'игнорировать'. Это решило проблему. Это поток с решением: stackoverflow.com/questions/10487563/…

Tim B 30.08.2018 03:46

Спасибо за отзыв @Greenstick. Ваши правки намного яснее, чем моя первоначальная попытка.

Tim B 30.08.2018 23:41

Рад помочь! И добро пожаловать в ТАК!

Greenstick 31.08.2018 18:54
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
7
275
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я опубликовал свое решение в комментариях выше; он должен был установить аргумент errors для open() на 'ignore':

with open(file, newline = '', errors='ignore') as f: 

Это именно то, что я искал в своем первом вопросе в исходном сообщении выше (т.е. есть ли способ указать csv.DictReader игнорировать неопределенные символы).

Обновление: позже мне пришлось работать с некоторыми символами Unicode, и я не мог их игнорировать. Правильный ответ для этого решения, основанного на файле unicode .csv, созданном в Excel, заключался в использовании кодека utf_8_sig. Это удаляет маркер порядка байтов (спецификация utf-16), который Windows записывает в верхней части файла, чтобы сообщить ей, что в нем есть символы Unicode.

Другие вопросы по теме