UnicodeDecodeError: 'utf8' codec tidak dapat mendekode byte 0xa5 di posisi 0: byte start tidak valid

188

Saya menggunakan Python-2.6 CGIskrip tetapi menemukan kesalahan ini di log server saat melakukan 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

Di sini

​__get​data()mengembalikan fungsi dictionary {}.

Sebelum posting pertanyaan ini saya telah disebut ini pertanyaan os SO.


PEMBARUAN

Baris berikut ini melukai encoder 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

Saya mendapat perbaikan sementara untuk itu

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

Tetapi saya tidak yakin apakah itu cara yang benar untuk melakukannya.

Deepak Ingole
sumber
1
Sepertinya Anda memiliki beberapa data string dalam kamus yang tidak dapat disandikan / didekodekan. Apa isinya dict?
mgilson
@mgilson yup master Saya mengerti masalah ini tetapi tidak tahu bagaimana mengatasinya .. dicttelahlist, dict, python timestamp value
Deepak Ingole
1
@ Pilot - Tidak juga. Masalah sebenarnya terkubur di suatu tempat di __getdata. Saya tidak tahu mengapa Anda mendapatkan karakter yang tidak dapat diterjemahkan. Anda dapat mencoba membuat tambalan pada dikt untuk membuatnya berfungsi, tetapi sebagian besar hanya meminta lebih banyak masalah nanti. Saya akan mencoba mencetak dict untuk melihat di mana karakter non-ascii berada. Kemudian cari tahu bagaimana bidang itu dihitung / ditetapkan dan bekerja mundur dari sana.
mgilson
1
Saya mengalami kesalahan yang sama ketika mencoba membaca file .csv yang memiliki beberapa karakter non-ascii di dalamnya. Menghapus karakter-karakter tersebut (seperti yang disarankan di bawah) menyelesaikan masalah.
Dmitriy R. Starson

Jawaban:

87

Kesalahannya adalah karena ada beberapa karakter non-ascii dalam kamus dan itu tidak dapat dikodekan / didekodekan. Salah satu cara sederhana untuk menghindari kesalahan ini adalah menyandikan string seperti itu dengan encode()fungsi sebagai berikut (jika astring dengan karakter non-ascii):

a.encode('utf-8').strip()
Santosh Ghimire
sumber
2
Karena UTF-8 kompatibel dengan ASCII 7-bit oldschool, Anda harus menyandikan semuanya. Untuk karakter dalam rentang ASCII 7-bit, pengkodean ini akan menjadi pemetaan identitas.
Tadeusz A. Kadłubowski
29
Tampaknya ini tidak begitu jelas. Saat mengimpor file csv, bagaimana Anda menggunakan kode ini?
Dave
Masalah yang sama muncul untuk saya ketika menjalankan kueri sqlalchemy, bagaimana saya menyandikan kueri (tidak memiliki .encode, karena ini bukan string)?
c8999c 3f964f64
130

Saya beralih ini hanya dengan mendefinisikan paket codec yang berbeda dalam read_csv()perintah:

encoding = 'unicode_escape'

Misalnya:

import pandas as pd
data = pd.read_csv(filename, encoding= 'unicode_escape')
MSalty
sumber
1
Hanya jika Anda menggunakanpandas
Valeriy
1
maaf, ini tidak berhasil, saya lagi memiliki kesalahan yang sama. tetapi ketika saya menggunakan ('filename.csv', engine = 'python'). Ini berhasil.
basavaraj_S
117

Coba cuplikan kode di bawah ini:

with open(path, 'rb') as f:
  text = f.read()
Karang
sumber
7
Saya rbukannya rb. terima kasih atas pengingat untuk ditambahkan b!
Paul
1
Secara default openfungsi memiliki 'r' sebagai mode hanya baca. rbsingkatan mode baca biner.
Siwa
39

String Anda memiliki asciikarakter non- dikodekan di dalamnya.

Tidak dapat memecahkan kode utf-8dapat terjadi jika Anda perlu menggunakan penyandian lain dalam kode Anda. Sebagai contoh:

>>> '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

Dalam hal ini, penyandiannya windows-1252harus Anda lakukan:

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

Sekarang Unicode, Anda dapat dengan mudah menyandikan utf-8.

JCF
sumber
1
Saya telah membuat halaman sederhana yang dapat membantu membangun pengkodean beberapa "byte misterius"; tripleee.github.io/8bit
tripleee
34

Saat membaca csv, saya menambahkan metode penyandian:

import pandas as pd
dataset = pd.read_csv('sample_data.csv', header= 0,
                        encoding= 'unicode_escape')
Krishna prasad.m
sumber
16

Tetapkan pembuat enkode default di bagian atas kode Anda

import sys
reload(sys)
sys.setdefaultencoding("ISO-8859-1")
HimalayanCoder
sumber
Saya pikir python3 tidak memiliki setdefaultencoding dalam modul sys!
Anwar Hossain
14

Pada 2018-05 ini ditangani langsung dengan decode, setidaknya untuk Python 3 .

Saya menggunakan cuplikan di bawah ini untuk invalid start bytedan invalid continuation bytemengetik kesalahan. Menambahkan errors='ignore'memperbaikinya untuk saya.

with open(out_file, 'rb') as f:
    for line in f:
        print(line.decode(errors='ignore'))
aaronpenne
sumber
1
Tentu saja, ini dengan diam-diam membuang informasi. Perbaikan yang lebih baik adalah mencari tahu apa yang seharusnya ada di sana, dan memperbaiki masalah aslinya.
tripleee
14

Terinspirasi oleh @aaronpenne dan @Soumyaansh

f = open("file.txt", "rb")
text = f.read().decode(errors='replace')
Punnerud
sumber
Saya mendapat "AttributeError: objek 'str' tidak memiliki atribut 'decode'". Tidak yakin apa yang salah?
Victor Wong
Apakah Anda memasukkan b ke "rb"? B adalah untuk membuka file sebagai byte-formated. Jika Anda hanya menggunakan r itu adalah string, dan jangan memasukkan decode.
Punnerud
14

Solusi ini bekerja untuk saya:

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

Solusi sederhana:

import pandas as pd
df = pd.read_csv('file_name.csv', engine='python')
Gil Baggio
sumber
3
Terima kasih sudah membantu!
Ruben
Senang membantu @Ruben
Gil Baggio
2
Terima kasih, ini membantu saya. Saya sedang mengerjakan panda. Terima kasih lagi
basavaraj_S
Senang membantu @basavaraj_S
Gil Baggio
1
Satu-satunya solusi yang berfungsi untuk saya dari semua yang disajikan di sini.
lunesco
7

Baris berikut ini melukai encoder 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

Saya mendapat perbaikan sementara untuk itu

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

Menandai ini benar sebagai perbaikan sementara (Tidak yakin begitu).

Deepak Ingole
sumber
5

Jika metode di atas tidak bekerja untuk Anda, Anda mungkin ingin melihat ke dalam mengubah pengkodean file csv itu sendiri.

Menggunakan Excel:

  1. Buka file csv menggunakan Excel
  2. Arahkan ke opsi "File menu" dan klik "Save As"
  3. Klik "Browse" untuk memilih lokasi untuk menyimpan file
  4. Masukkan nama file yang dimaksud
  5. Pilih opsi CSV (Comma delimited) (* .csv)
  6. Klik kotak drop-down "Alat" dan klik "Opsi Web"
  7. Di bawah tab "Encoding", pilih opsi Unicode (UTF-8) dari "Simpan dokumen ini sebagai" daftar turun bawah
  8. Simpan file

Menggunakan Notepad:

  1. Buka file csv menggunakan notepad
  2. Buka opsi "File"> "Save As"
  3. Selanjutnya, pilih lokasi ke file
  4. Pilih opsi Simpan sebagai tipe sebagai Semua File ( . )
  5. Tentukan nama file dengan ekstensi .csv
  6. Dari daftar drop-down "Pengkodean", pilih opsi UTF-8.
  7. Klik Simpan untuk menyimpan file

Dengan melakukan ini, Anda seharusnya dapat mengimpor file csv tanpa menemui UnicodeCodeError.

Zuo
sumber
2

Setelah mencoba semua solusi yang disebutkan di atas, jika masih menghasilkan kesalahan yang sama, Anda dapat mencoba mengekspor file sebagai CSV (kedua kalinya jika sudah). Terutama jika Anda menggunakan scikit belajar, yang terbaik adalah mengimpor dataset sebagai file CSV.

Saya menghabiskan waktu berjam-jam bersama, sedangkan solusinya sangat sederhana. Ekspor file sebagai CSV ke direktori tempat Anaconda atau alat pengklasifikasi Anda diinstal dan coba.

Sushmita
sumber
2

Anda dapat menggunakan pengkodean standar untuk penggunaan dan input spesifik Anda.

utf-8 adalah standarnya.

iso8859-1 juga populer di Eropa Barat.

misalnya: bytes_obj.decode('iso8859-1')

lihat: docs

NoamG
sumber
1
Menebak pengkodean secara buta cenderung menghasilkan lebih banyak kesalahan. Memilih iso8859-1 atau cp1251 dll tanpa benar-benar mengetahui pengkodean file mana yang akan menghapus gejala, tetapi menghasilkan sampah jika Anda salah menebak. Jika hanya beberapa byte, mungkin perlu bertahun-tahun sebelum Anda melihat dan memperbaiki kesalahan sebenarnya .
tripleee