UnicodeDecodeError: kodek „charmap” nie może dekodować bajtu X w pozycji Y: znak odwzorowuje na <nieokreślony>


549

Próbuję uzyskać program w języku Python 3 do wykonywania pewnych operacji przy użyciu pliku tekstowego wypełnionego informacjami. Jednak podczas próby odczytania pliku pojawia się następujący błąd:

 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
Dla tego samego błędu rozwiązanie to pomogło mi, rozwiązanie błędu charmap
Shubham Sharma

2
Zobacz Przetwarzanie plików tekstowych w Pythonie 3, aby zrozumieć, dlaczego występuje ten błąd.
Andreas Haferburg

Odpowiedzi:


960

Plik, o którym mowa, nie korzysta z CP1252kodowania. Używa innego kodowania. Który musisz sam wymyślić. Typowe są Latin-1i UTF-8. Ponieważ 0x90 tak naprawdę nic nie znaczy Latin-1, UTF-8(gdzie 0x90 jest bajtem kontynuacji) jest bardziej prawdopodobne.

Określasz kodowanie podczas otwierania pliku:

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

19
Fajnie, miałem ten problem z jakimś kodem Python 2.7, który próbowałem uruchomić w Pythonie 3.4. Latin-1 pracował dla mnie!
1vand1ng0

2
jeśli używasz Python 2.7 i otrzymujesz ten sam błąd, wypróbuj iomoduł:io.open(filename,encoding="utf8")
christopherlovell

9
@ 1vand1ng0: oczywiście działa Latin-1; będzie działać dla każdego pliku, niezależnie od faktycznego kodowania pliku. Wynika to z faktu, że wszystkie 256 możliwych wartości bajtów w pliku ma punkt kodowy Latin-1, na który ma być mapowane, ale to nie znaczy, że otrzymujesz czytelne wyniki! Jeśli nie znasz kodowania, nawet otwarcie pliku w trybie binarnym może być lepsze niż przyjęcie Latin-1.
Martijn Pieters

1
Domyślnie jest to Unicode, ale Unicode nie jest kodowaniem. regebro.wordpress.com/2011/03/23/…
Lennart Regebro

1
filename = "C:\Report.txt" with open(filename,encoding ="utf8") as my_file: text = my_file.read() print(text)nawet po użyciu otrzymuję ten sam błąd. Próbowałem też z innym kodowaniem, ale wszystko na próżno. W tym kodzie również używam from geotext import GeoText. Proszę zaproponować rozwiązanie.
Salah

47

Tylko dodać, jeśli file = open(filename, encoding="utf8")nie działa spróbujfile = open(filename, errors='ignore')


Wielkie dzięki - spróbuję. W niektórych częściach plików nie ma znaczenia, czy są jakieś nieprawidłowe znaki.
Stephen Nutt

6
Ostrzeżenie: spowoduje to utratę danych w przypadku napotkania nieznanych znaków (co może być w porządku w zależności od twojej sytuacji).
Hans Goldman

34

Jako rozszerzenie odpowiedzi @ LennartRegebro :

Jeśli nie możesz powiedzieć, jakiego kodowania używa Twój plik, a powyższe rozwiązanie nie działa (nie jest utf8), a znalazłeś się tylko w zgadywaniu - istnieją narzędzia online , za pomocą których można zidentyfikować, jakie to kodowanie. Nie są idealne, ale zwykle działają dobrze. Po ustaleniu kodowania powinieneś być w stanie użyć powyższego rozwiązania.

EDYCJA: (Skopiowane z komentarza)

Dość popularny edytor tekstowy Sublime Textma polecenie wyświetlania kodowania, jeśli zostało ustawione ...

  1. Idź do View-> Show Console(lub Ctrl+ `)

wprowadź opis zdjęcia tutaj

  1. Wpisz w pole u dołu view.encoding()i Undefinedmiej nadzieję na najlepsze (nie udało mi się nic dostać, ale może będziesz mieć więcej szczęścia ...)

wprowadź opis zdjęcia tutaj


2
Niektóre edytory tekstu również podają te informacje. Wiem, że dzięki vimowi możesz to uzyskać za pośrednictwem :set fileencoding( z tego linku )
PaxRomana99

3
Sublime Text, także - otwórz konsolę i wpisz view.encoding().
JimmidyJoo

alternatywnie możesz otworzyć plik za pomocą notatnika. „Zapisz jako”, a zobaczysz listę rozwijaną z zastosowanym kodowaniem
don_Gunner94

9

Alternatywnie, jeśli nie trzeba dekodować pliku, takie jak przesyłanie plików do serwisów open(filename, 'rb'). r = odczyt, b = binarny


Dziękuję, że tak było w przypadku mojego problemu
shahin gh

6

TLDR? Próbować:file = open(filename, encoding='cp437)

Dlaczego? Gdy jedno użycie:

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

Python zakłada, że ​​plik używa tej samej strony kodowej co bieżące środowisko (cp1252 w przypadku postu otwierającego) i próbuje zdekodować go do własnego domyślnego UTF-8. Jeśli plik zawiera znaki o wartościach niezdefiniowanych na tej stronie kodowej (np. 0x90), otrzymujemy błąd UnicodeDecodeError. Czasami nie znamy kodowania pliku, czasem kodowanie pliku może być nieobsługiwane przez Python (np. Cp790), czasem plik może zawierać kodowanie mieszane.

Jeśli takie znaki nie są potrzebne, można zdecydować o ich zastąpieniu znakami zapytania:

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

Innym obejściem jest użycie:

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

Znaki pozostaną nienaruszone, ale inne błędy również zostaną zamaskowane.

Całkiem dobrym rozwiązaniem jest określenie kodowania, ale nie kodowania (jak cp1252), ale takiego, w którym zdefiniowano WSZYSTKIE znaki (jak cp437):

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

Strona kodowa 437 to oryginalne kodowanie DOS. Wszystkie kody są zdefiniowane, więc nie ma błędów podczas odczytu pliku, żadnych błędów jest maskowanych, znaki są zachowywane (niezupełnie pozostawione nienaruszone, ale nadal możliwe do odróżnienia).


1
Wow, dziękuje. To jest dla mnie jedyne dekodowanie.
Kowalski

1

Dla osób pracujących w Anaconda w systemie Windows miałem ten sam problem. Notepad ++ pomóż mi go rozwiązać.

Otwórz plik w Notepad ++. W prawym dolnym rogu pokaże ci bieżące kodowanie pliku. W górnym menu obok „Widok” znajdź „Kodowanie”. W „Kodowaniu” przejdź do „zestawów znaków” i tam wraz z pacjentem szukaj kodowania, którego potrzebujesz. W moim przypadku kodowanie „Windows-1252” znaleziono w „Zachodnioeuropejskim”


1

Przestań marnować czas, po prostu dodaj następujące elementy encoding="cp437"i errors='ignore'do kodu zarówno w trybie odczytu, jak i zapisu:

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

Życzenia powodzenia


Jasne, proszę pana. Przyjąłem. Nie marnuj czasu. Dziękuję Ci. Napijesz się kawy lub dobrego wina?
Pramesh Bajracharya

0

dla mnie zmiana kodowania Mysql na taki sam jak mój kod pomogła w rozwiązaniu problemu. `photo = open ('pic3.png', kodowanie = latin1), silny tekst wprowadź opis zdjęcia tutaj

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.