UnicodeDecodeError: кодек "charmap" не може розшифрувати байт X у положенні Y: символи відображаються на <undefined>


549

Я намагаюся змусити програму Python 3 зробити деякі маніпуляції з текстовим файлом, наповненим інформацією. Однак, намагаючись прочитати файл, я отримую таку помилку:

 Traceback (most recent call last):  
     File "SCRIPT LOCATION", line NUMBER, in <module>  
     `text = file.read()`  
     File "C:\Python31\lib\encodings\cp1252.py", line 23, in decode  
     `return codecs.charmap_decode(input,self.errors,decoding_table)[0]`  
     UnicodeDecodeError: 'charmap' codec can't decode byte 0x90 in position 2907500: character maps to `<undefined>`  

2
З тієї ж помилки мені допомогло це рішення, рішення помилки charmap
Shubham Sharma

2
Див. Розділ Обробка текстових файлів у Python 3, щоб зрозуміти, чому ви отримуєте цю помилку.
Андреас Хафербург

Відповіді:


960

У розглянутому файлі не використовується CP1252кодування. Він використовує інше кодування. Який ви повинні самі з'ясувати. Поширеними є Latin-1і UTF-8. Оскільки 0x90 насправді нічого не означає Latin-1, UTF-8( 0x90 - байт продовження) є більш імовірним.

Кодування ви вказуєте під час відкриття файлу:

file = open(filename, encoding="utf8")

19
Класно, у мене була проблема з деяким кодом Python 2.7, який я намагався запустити в Python 3.4. Латинська-1 працювала на мене!
1vand1ng0

2
якщо ви використовуєте Python 2.7 і отримуєте ту ж помилку, спробуйте ioмодуль:io.open(filename,encoding="utf8")
christopherlovell

9
@ 1vand1ng0: звичайно, працює латинська мова-1; він працюватиме для будь-якого файлу незалежно від того, що фактично кодує файл. Це тому, що всі 256 можливих байтових значень у файлі мають кодову точку Latin-1, яку потрібно зіставити, але це не означає, що ви отримаєте розбірливі результати! Якщо ви не знаєте кодування, навіть відкриття файлу у двійковому режимі може бути краще, ніж припускати Latin-1.
Martijn Pieters

1
За замовчуванням це unicode, але unicode - не кодування. regebro.wordpress.com/2011/03/23/…
Леннарт Регебро

1
filename = "C:\Report.txt" with open(filename,encoding ="utf8") as my_file: text = my_file.read() print(text)навіть після використання цього я отримую ту ж помилку. Я також пробував з іншим кодуванням, але все даремно. У цьому коді я також використовую from geotext import GeoText. Просимо запропонувати рішення.
Салах

47

Просто додати, якщо file = open(filename, encoding="utf8")не виходить, спробуйтеfile = open(filename, errors='ignore')


Велике спасибі - я спробую це. У деяких файлах, які мене не цікавлять, є деякі недійсні символи.
Стівен Натт

6
Попередження: Це призведе до втрати даних, коли зустрінуться невідомі символи (що може бути добре залежно від вашої ситуації).
Ганс Голдман

34

Як додаток до відповіді @ LennartRegebro :

Якщо ви не можете сказати, яке кодування використовує ваш файл, і рішення, яке описано вище, не працює (це не так utf8), і ви виявили, що ви просто здогадуєтесь - є онлайн-інструменти, які ви можете використати для визначення того, що таке кодування. Вони не ідеальні, але зазвичай працюють просто чудово. Після того як ви з'ясуєте кодування, ви повинні мати можливість використовувати рішення вище.

Редагувати: (Скопійовано з коментаря)

Досить популярний текстовий редактор Sublime Textмає команду відображення кодування, якщо воно було встановлено ...

  1. Перейти до View-> Show Console(або Ctrl+ `)

введіть тут опис зображення

  1. Введіть поле внизу view.encoding()і сподівайтеся на найкраще (я нічого не зміг отримати, Undefinedале, можливо, у вас буде більше удачі ...)

введіть тут опис зображення


2
Деякі текстові редактори також надаватимуть цю інформацію. Я знаю, що з vim ви можете отримати це через :set fileencoding( за цим посиланням )
PaxRomana99

3
Піднесений текст, також - відкрийте консоль і наберіть view.encoding().
JimmidyJoo

Ви також можете відкрити свій файл із блокнотом. "Зберегти як", і ви побачите спадне меню із застосованим кодуванням
don_Gunner94

9

Крім того, якщо вам не потрібно декодувати файл, наприклад, завантаження файлу на веб - сайт, open(filename, 'rb'). r = читання, b = двійкове


Дякую, що це
shahin gh

6

TLDR? Спробуйте:file = open(filename, encoding='cp437)

Чому? При одному використанні:

file = open(filename)
text = file.read()

Python передбачає, що файл використовує ту саму кодову сторінку, що і поточне середовище (cp1252 у випадку відкриття) та намагається розшифрувати його до власного UTF-8 за замовчуванням. Якщо файл містить символи значень, не визначених на цій кодовій сторінці (наприклад, 0x90), ми отримуємо UnicodeDecodeError. Іноді ми не знаємо кодування файлу, іноді кодування файлу може бути оброблено Python (наприклад, cp790), іноді файл може містити змішані кодування.

Якщо такі символи не потрібні, можна вирішити замінити їх знаками запитання на:

file = open(filename, errors='replace')

Іншим способом вирішення є використання:

file = open(filename, errors='ignore')

Потім символи залишаються неушкодженими, але інші помилки також будуть замасковані.

Досить вдалим рішенням є визначення кодування, але не будь-яке кодування (наприклад, cp1252), а таке, яке має ВСІ символи (наприклад, cp437):

file = open(filename, encoding='cp437')

Кодова сторінка 437 - це оригінальне кодування DOS. Усі коди визначені, тому помилок під час читання файлу немає, помилок не маскується, символи зберігаються (не зовсім залишені недоторканими, але все ще помітні).


1
Нічого собі, тихо. Це єдине для мене декодування.
Ковальський

1

Для тих, хто працює в Anaconda в Windows, у мене була така ж проблема. Блокнот ++ допоможе мені вирішити це.

Відкрийте файл у Блокноті ++. Праворуч внизу він повідомить вам про кодування поточного файлу. У верхньому меню поруч із пунктом "Перегляд" знайдіть "Кодування". У розділі "Кодування" перейдіть до "наборів символів" і там терпляче шукайте обшивку, яке вам потрібно. У моєму випадку кодування "Windows-1252" було знайдено під "Західноєвропейським"


1

Досить витрачати свій час, просто додайте наступну рядок encoding="cp437"і errors='ignore'в свій код в обох читання і запису:

open('filename.csv', encoding="cp437", errors='ignore')
open(file_name, 'w', newline='', encoding="cp437", errors='ignore')

Швидкість


Звичайно, сер. Роджер, що. Не витрачали часу. Дякую. Хочеш чашку кави чи прекрасного вина?
Прамеш Байрачаря

0

для мене зміна кодування символів Mysql так само, як мій код, допомогла розібратися в рішенні. `photo = open ('pic3.png', encoding = latin1), сильний текст введіть тут опис зображення

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.