UnicodeDecodeError: codec 'charmap' không thể giải mã byte X ở vị trí Y: ánh xạ ký tự thành <không xác định>


549

Tôi đang cố gắng để chương trình Python 3 thực hiện một số thao tác với tệp văn bản chứa đầy thông tin. Tuy nhiên, khi cố đọc tệp tôi gặp lỗi sau:

 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
Đối với cùng một lỗi, giải pháp này đã giúp tôi, giải pháp cho lỗi charmap
Shubham Sharma

2
Xem Xử lý tệp văn bản trong Python 3 để hiểu lý do tại sao bạn gặp lỗi này.
Andreas Haferburg

Câu trả lời:


960

Các tập tin trong câu hỏi không sử dụng CP1252mã hóa. Đó là sử dụng mã hóa khác. Cái nào bạn phải tự tìm ra. Những cái phổ biến là Latin-1UTF-8. Vì 0x90 thực sự không có nghĩa gì cả Latin-1, UTF-8(trong đó 0x90 là byte tiếp tục) có nhiều khả năng.

Bạn chỉ định mã hóa khi bạn mở tệp:

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

19
Thật tuyệt, tôi đã gặp vấn đề đó với một số mã Python 2.7 mà tôi đã cố chạy trong Python 3.4. Latin-1 làm việc cho tôi!
1vand1ng0

2
nếu bạn đang sử dụng Python 2.7 và gặp lỗi tương tự, hãy thử iomô-đun:io.open(filename,encoding="utf8")
christopherlovell

9
@ 1vand1ng0: tất nhiên các tác phẩm Latin-1; nó sẽ hoạt động cho bất kỳ tệp nào bất kể mã hóa thực tế của tệp là gì. Đó là bởi vì tất cả 256 giá trị byte có thể có trong một tệp đều có mã số Latin-1 để ánh xạ tới, nhưng điều đó không có nghĩa là bạn nhận được kết quả rõ ràng! Nếu bạn không biết mã hóa, thậm chí mở tệp ở chế độ nhị phân thay vào đó có thể tốt hơn giả sử Latin-1.
Martijn Pieters

1
Nó là unicode theo mặc định, nhưng unicode không phải là mã hóa. regebro.wordpress.com/2011/03/23/ cường
Lennart Regebro 16/2/18

1
filename = "C:\Report.txt" with open(filename,encoding ="utf8") as my_file: text = my_file.read() print(text)ngay cả sau khi sử dụng tôi cũng nhận được lỗi tương tự. Tôi cũng đã thử với mã hóa khác nhưng tất cả đều vô ích. Trong mã này tôi cũng đang sử dụng from geotext import GeoText. Xin đề xuất một giải pháp.
Salah

47

Chỉ cần thêm vào trong trường hợp file = open(filename, encoding="utf8")không hoạt động thửfile = open(filename, errors='ignore')


Rất cám ơn - tôi sẽ thử cái này Có một số ký tự không hợp lệ trong các phần của tệp mà tôi không quan tâm.
Stephen Nutt

6
Cảnh báo: Điều này sẽ dẫn đến mất dữ liệu khi gặp phải các ký tự không xác định (có thể ổn tùy theo tình huống của bạn).
Hans Goldman

34

Là một phần mở rộng cho câu trả lời của @ LennartRegebro :

Nếu bạn không thể biết mã hóa tập tin của mình sử dụng và giải pháp ở trên không hoạt động (không phải vậy utf8) và bạn chỉ thấy mình đang đoán - có những công cụ trực tuyến mà bạn có thể sử dụng để xác định mã hóa đó là gì. Chúng không hoàn hảo nhưng thường hoạt động tốt. Sau khi bạn tìm ra mã hóa, bạn sẽ có thể sử dụng giải pháp ở trên.

EDIT: (Sao chép từ bình luận)

Một trình soạn thảo văn bản khá phổ biến Sublime Textcó lệnh hiển thị mã hóa nếu nó đã được đặt ...

  1. Chuyển đến View-> Show Console(hoặc Ctrl+ `)

nhập mô tả hình ảnh ở đây

  1. Nhập vào trường ở phía dưới view.encoding()và hy vọng điều tốt nhất (tôi không thể có được bất cứ điều gì Undefinednhưng có lẽ bạn sẽ gặp may mắn hơn ...)

nhập mô tả hình ảnh ở đây


2
Một số biên tập viên văn bản sẽ cung cấp thông tin này là tốt. Tôi biết rằng với vim bạn có thể nhận được điều này qua :set fileencoding( từ liên kết này )
PaxRomana99

3
Sublime Text, cũng - mở giao diện điều khiển và gõ view.encoding().
JimmidyJoo

Ngoài ra, bạn có thể mở tệp của bạn bằng notepad. 'Lưu dưới dạng' và bạn sẽ thấy trình đơn thả xuống với mã hóa được sử dụng
don_Gunner94

9

Ngoài ra, nếu bạn không cần giải mã tệp, chẳng hạn như tải tệp lên trang web , open(filename, 'rb'). r = đọc, b = nhị phân


Cảm ơn bạn đó là trường hợp cho vấn đề của tôi
shahin gh

6

TLDR? Thử:file = open(filename, encoding='cp437)

Tại sao? Khi một người sử dụng:

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

Python giả định tệp sử dụng cùng một bảng mã như môi trường hiện tại (cp1252 trong trường hợp bài đăng mở) và cố gắng giải mã nó thành UTF-8 mặc định của chính nó. Nếu tệp chứa các ký tự của các giá trị không được xác định trong bảng mã này (như 0x90), chúng tôi sẽ nhận được UnicodeDecodeError. Đôi khi chúng ta không biết mã hóa tệp, đôi khi mã hóa của tệp có thể được xử lý bởi Python (ví dụ: cp790), đôi khi tệp có thể chứa mã hóa hỗn hợp.

Nếu các ký tự đó không cần thiết, người ta có thể quyết định thay thế chúng bằng dấu chấm hỏi, bằng:

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

Một cách giải quyết khác là sử dụng:

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

Các ký tự sau đó được giữ nguyên, nhưng các lỗi khác cũng sẽ bị che đi.

Giải pháp khá tốt là chỉ định mã hóa, nhưng không phải bất kỳ mã hóa nào (như cp1252), nhưng mã hóa có TẤT CẢ các ký tự được xác định (như cp437):

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

Codepage 437 là mã hóa DOS gốc. Tất cả các mã được xác định, do đó không có lỗi trong khi đọc tệp, không có lỗi được che dấu, các ký tự được giữ nguyên (không còn nguyên vẹn nhưng vẫn có thể phân biệt được).


1
Wow, thaks bạn. Đây là giải mã duy nhất làm việc cho tôi.
Cửu Long

1

Đối với những người làm việc trong Anaconda trong Windows, tôi cũng gặp vấn đề tương tự. Notepad ++ giúp tôi giải quyết nó.

Mở tệp trong Notepad ++. Ở dưới cùng bên phải, nó sẽ cho bạn biết mã hóa tập tin hiện tại. Trong menu trên cùng, bên cạnh "Xem" định vị "Mã hóa". Trong "Mã hóa", hãy chuyển đến "bộ ký tự" và ở đó với sự kiên nhẫn tìm kiếm sự bao bọc mà bạn cần. Trong trường hợp của tôi, mã hóa "Windows-1252" đã được tìm thấy trong "Tây Âu"


1

Ngừng lãng phí thời gian của bạn, chỉ cần thêm những điều sau đây encoding="cp437"errors='ignore'vào mã của bạn trong cả đọc và viết:

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

Thần tốc độ


Hẳn vậy rồi sếp. Roger đó. Không lãng phí thời gian. Cảm ơn bạn. Bạn có muốn một tách cà phê hoặc rượu vang tốt?
Pramesh Bajracharya

0

đối với tôi, việc thay đổi mã hóa ký tự Mysql giống như mã của tôi đã giúp sắp xếp giải pháp. `photo = open ('pic3.png', mã hóa = latin1), văn bản mạnh nhập mô tả hình ảnh ở đây

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.