UnicodeDecodeError: 'utf8' codec không thể giải mã byte 0xa5 ở vị trí 0: byte bắt đầu không hợp lệ


188

Tôi đang sử dụng Python-2.6 CGItập lệnh nhưng tìm thấy lỗi này trong nhật ký máy chủ trong khi thực hiện json.dumps(),

Traceback (most recent call last):
  File "/etc/mongodb/server/cgi-bin/getstats.py", line 135, in <module>
    print json.dumps(​​__getdata())
  File "/usr/lib/python2.7/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/usr/lib/python2.7/json/encoder.py", line 201, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python2.7/json/encoder.py", line 264, in iterencode
    return _iterencode(o, 0)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xa5 in position 0: invalid start byte

Đây

​__get​data()trả về hàm dictionary {}.

Trước khi đăng câu hỏi này, tôi đã gọi này của câu hỏi os SO.


CẬP NHẬT

Dòng sau đang làm tổn thương bộ mã hóa JSON,

now = datetime.datetime.now()
now = datetime.datetime.strftime(now, '%Y-%m-%dT%H:%M:%S.%fZ')
print json.dumps({'current_time': now}) // this is the culprit

Tôi đã có một sửa chữa tạm thời cho nó

print json.dumps( {'old_time': now.encode('ISO-8859-1').strip() })

Nhưng tôi không chắc chắn đó là cách chính xác để làm điều đó.


1
Có vẻ như bạn có một số dữ liệu chuỗi trong từ điển không thể được mã hóa / giải mã. Có gì trong dict?
mgilson

@mgilson yup master Tôi hiểu vấn đề nhưng không biết làm thế nào để đối phó với nó .. dictđãlist, dict, python timestamp value
Deepak Ingole

1
@Pilot - Không hẳn. Vấn đề thực sự được chôn giấu ở đâu đó trong __getdata. Tôi không biết tại sao bạn nhận được một nhân vật không thể giải mã. Bạn có thể cố gắng đưa ra các bản vá trên dict để làm cho nó hoạt động, nhưng những thứ đó chủ yếu chỉ là yêu cầu nhiều vấn đề hơn sau này. Tôi sẽ thử in dict để xem nhân vật không phải là ascii ở đâu. Sau đó tìm hiểu làm thế nào trường đó đã được tính toán / thiết lập và làm việc lạc hậu từ đó.
mgilson


1
Tôi đã gặp lỗi tương tự khi cố gắng đọc tệp .csv có một số ký tự không phải mã ascii trong đó. Loại bỏ các ký tự (như đề xuất dưới đây) đã giải quyết vấn đề.
Dmitriy R. Starson

Câu trả lời:


87

Lỗi là do có một số ký tự không phải mã ascii trong từ điển và nó không thể được mã hóa / giải mã. Một cách đơn giản để tránh lỗi này là mã hóa các chuỗi như vậy với encode()chức năng như sau (nếu alà chuỗi có ký tự không phải mã ascii):

a.encode('utf-8').strip()

2
Vì UTF-8 tương thích ngược với ASCII 7 bit cũ, bạn chỉ nên mã hóa mọi thứ. Đối với các ký tự trong phạm vi ASCII 7 bit, mã hóa này sẽ là ánh xạ định danh.
Tadeusz A. Kadłubowski

29
Điều này dường như không thực sự rõ ràng. Khi nhập tệp csv, bạn sử dụng mã này như thế nào?
Dave

Vấn đề tương tự xuất hiện với tôi khi thực hiện truy vấn sqlalchemy, làm thế nào để tôi mã hóa truy vấn (không có .encode, vì nó không phải là một chuỗi)?
c8999c 3f964f64

129

Tôi đã chuyển đổi điều này đơn giản bằng cách định nghĩa một gói codec khác trong read_csv()lệnh:

encoding = 'unicode_escape'

Ví dụ:

import pandas as pd
data = pd.read_csv(filename, encoding= 'unicode_escape')

1
Chỉ khi bạn sử dụngpandas
Valeriy

1
xin lỗi, điều này không hoạt động, tôi lại gặp lỗi tương tự. nhưng khi tôi sử dụng ('filename.csv', engine = 'python'). Điều này đã làm việc.
basavaraj_S

117

Hãy thử đoạn mã dưới đây:

with open(path, 'rb') as f:
  text = f.read()

7
Tôi đã rthay thế rb. cảm ơn đã nhắc nhở để thêm b!
Paul

1
Theo mặc định, openchức năng có 'r' là chế độ chỉ đọc. rblà viết tắt của chế độ nhị phân đọc.
Shiva

39

Chuỗi của bạn có một asciiký tự không được mã hóa trong đó.

Không thể giải mã với utf-8có thể xảy ra nếu bạn cần sử dụng các bảng mã khác trong mã của mình. Ví dụ:

>>> 'my weird character \x96'.decode('utf-8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python27\lib\encodings\utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0x96 in position 19: invalid start byte

Trong trường hợp này, mã hóa là windows-1252do đó bạn phải làm:

>>> 'my weird character \x96'.decode('windows-1252')
u'my weird character \u2013'

Bây giờ bạn có Unicode, bạn có thể mã hóa một cách an toàn utf-8.


1
Tôi đã tạo một trang đơn giản có thể giúp thiết lập mã hóa một số "byte bí ẩn" bất ngờ; tripleee.github.io/8bit
tripleee

34

Khi đọc csv, tôi đã thêm một phương thức mã hóa:

import pandas as pd
dataset = pd.read_csv('sample_data.csv', header= 0,
                        encoding= 'unicode_escape')

16

Đặt bộ mã hóa mặc định ở đầu mã của bạn

import sys
reload(sys)
sys.setdefaultencoding("ISO-8859-1")

Tôi nghĩ python3 không có setdefaultencoding trong mô-đun sys!
Anwar Hossain

14

Kể từ 2018-05, điều này được xử lý trực tiếp với decode, ít nhất là đối với Python 3 .

Tôi đang sử dụng đoạn mã dưới đây invalid start byteinvalid continuation bytelỗi loại. Thêm errors='ignore'cố định nó cho tôi.

with open(out_file, 'rb') as f:
    for line in f:
        print(line.decode(errors='ignore'))

1
Tất nhiên, điều này âm thầm loại bỏ thông tin. Cách khắc phục tốt hơn nhiều là tìm ra những gì được cho là ở đó và khắc phục vấn đề ban đầu.
tripleee

14

Lấy cảm hứng từ @aaronpenne và @Soumyaansh

f = open("file.txt", "rb")
text = f.read().decode(errors='replace')

Tôi đã nhận được "AttributionError: 'str' object không có thuộc tính 'decode'". Không chắc chắn những gì đã đi sai?
Victor Wong

Bạn đã bao gồm b đến "rb"? B là để mở tệp dưới dạng byte. Nếu bạn chỉ sử dụng r thì đó là chuỗi và không bao gồm giải mã.
Punnerud

14

Giải pháp này hiệu quả với tôi:

import pandas as pd
data = pd.read_csv("training.csv", encoding = 'unicode_escape')

11

Giải pháp đơn giản:

import pandas as pd
df = pd.read_csv('file_name.csv', engine='python')

3
Cảm ơn đã giúp!
Ruben

Vui mừng được giúp đỡ @Ruben
Gil Baggio

2
Cảm ơn bạn điều này đã giúp tôi. Tôi đã làm việc trên gấu trúc. Cảm ơn một lần nữa
basavaraj_S

Rất vui được giúp đỡ @basavaraj_S
Gil Baggio

1
Giải pháp duy nhất phù hợp với tôi trong số tất cả những người trình bày ở đây.
lunesco

7

Dòng sau đang làm tổn thương bộ mã hóa JSON,

now = datetime.datetime.now()
now = datetime.datetime.strftime(now, '%Y-%m-%dT%H:%M:%S.%fZ')
print json.dumps({'current_time': now}) // this is the culprit

Tôi đã có một sửa chữa tạm thời cho nó

print json.dumps( {'old_time': now.encode('ISO-8859-1').strip() })

Đánh dấu điều này là chính xác như là một sửa chữa tạm thời (Không chắc chắn như vậy).


5

Nếu các phương pháp trên không hiệu quả với bạn, bạn có thể muốn xem xét việc thay đổi mã hóa của tệp csv.

Sử dụng Excel:

  1. Mở tệp csv bằng Excel
  2. Điều hướng đến tùy chọn "Menu tệp" và nhấp vào "Lưu dưới dạng"
  3. Nhấp vào "Duyệt" để chọn một vị trí để lưu tệp
  4. Nhập tên tệp dự định
  5. Chọn tùy chọn CSV (được phân cách bằng dấu phẩy) (* .csv)
  6. Nhấp vào hộp thả xuống "Công cụ" và nhấp vào "Tùy chọn web"
  7. Trong tab "Mã hóa", chọn tùy chọn Unicode (UTF-8) từ danh sách thả xuống "Lưu tài liệu này dưới dạng"
  8. Lưu các tập tin

Sử dụng Notepad:

  1. Mở tệp csv bằng notepad
  2. Điều hướng đến tùy chọn "Tệp"> "Lưu dưới dạng"
  3. Tiếp theo, chọn vị trí để tập tin
  4. Chọn tùy chọn Lưu dưới dạng là Tất cả Tệp ( . )
  5. Chỉ định tên tệp có đuôi .csv
  6. Từ danh sách thả xuống "Mã hóa", chọn tùy chọn UTF-8.
  7. Nhấp vào Lưu để lưu tệp

Bằng cách này, bạn sẽ có thể nhập tệp csv mà không gặp phải UnicodeCodeError.


2

Sau khi thử tất cả các cách giải quyết đã nói ở trên, nếu nó vẫn gây ra lỗi tương tự, bạn có thể thử xuất tệp dưới dạng CSV (lần thứ hai nếu bạn đã có). Đặc biệt nếu bạn đang sử dụng scikit learn, tốt nhất là nhập tập dữ liệu dưới dạng tệp CSV.

Tôi đã dành hàng giờ với nhau, trong khi giải pháp là đơn giản. Xuất tệp dưới dạng CSV sang thư mục nơi Anaconda hoặc các công cụ phân loại của bạn được cài đặt và thử.


2

Bạn có thể sử dụng bất kỳ mã hóa tiêu chuẩn của việc sử dụng và đầu vào cụ thể của bạn.

utf-8 là mặc định

iso8859-1 cũng phổ biến cho Tây Âu.

ví dụ: bytes_obj.decode('iso8859-1')

xem: tài liệu


1
Đoán mù quáng mã hóa có khả năng tạo ra nhiều lỗi hơn. Chọn iso8859-1 hoặc cp1251, v.v. mà không thực sự biết mã hóa mà tập tin sử dụng sẽ loại bỏ triệu chứng này, nhưng sẽ tạo ra rác nếu bạn đoán sai. Nếu chỉ là một vài byte, có thể mất nhiều năm trước khi bạn nhận thấy và sửa lỗi thực sự .
tripleee

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.