UnicodeDecodeError: 'utf8' kodeki 0 konumunda bayt 0xa5 kodunu çözemiyor: geçersiz başlangıç ​​baytı


188

Ben Python-2.6 CGIkomut dosyaları kullanıyorum ama bu hatayı yaparken sunucu günlüğünde buldum 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

İşte,

​__get​data()işlevi geri döner dictionary {}.

Bu soru göndermeden önce ben atıf yaptığı bu soru os SO.


GÜNCEL

Aşağıdaki satır JSON kodlayıcısına zarar veriyor,

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

Bunun için geçici bir düzeltme aldım

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

Ama bunu yapmanın doğru yolu olduğundan emin değilim.


1
Sözlükte kodlanamayan / kodu çözülemeyen bazı dize verileriniz var gibi görünüyor. İçinde ne var dict?
mgilson

@mgilson yup master Sorunu anladım ama onunla nasıl başa çıkacağımı bilmiyorum .. dicthaslist, dict, python timestamp value
Deepak Ingole

1
@Pilot - Pek değil. Asıl sorun bir yerlerde gömülü __getdata. Neden çözülemeyen bir karakter aldığını bilmiyorum . Çalıştırmak için dikte yamalar bulmayı deneyebilirsiniz, ancak bunlar daha sonra sadece daha fazla sorun istiyor. Ascii olmayan karakterin nerede olduğunu görmek için dikteyi yazdırmayı denerdim. Sonra bu alanın nasıl hesaplandığını / ayarlandığını ve oradan geriye doğru çalıştığını anlayın.
mgilson


1
İçinde bazı ascii olmayan karakterler olan bir .csv dosyasını okumaya çalışırken aynı hatayla karşılaştım. Bu karakterleri kaldırmak (aşağıda önerildiği gibi) sorunu çözdü.
Dmitriy R. Starson

Yanıtlar:


87

Hata, sözlükte bazı ascii olmayan karakterlerin bulunması ve kodlanamaması / kodu çözülememesidir. Bu hatayı önlemenin basit bir yolu, bu tür dizeleri encode()aşağıdaki gibi işlevle kodlamaktır (eğer aascii olmayan karaktere sahip dize ise):

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

2
UTF-8, eski okul 7-bit ASCII ile geri uyumlu olduğundan, her şeyi kodlamanız gerekir. 7 bitlik ASCII aralığındaki karakterler için bu kodlama bir kimlik eşlemesi olacaktır.
Tadeusz A. Kadłubowski

29
Bu çok net görünmüyor. Bir csv dosyasını alırken bu kodu nasıl kullanıyorsunuz?
Dave

Aynı sorun benim için bir sqlalchemy sorgusu yürütülürken görünür, sorguyu nasıl kodlarım (dize olmadığı için .encode yok)?
c8999c 3f964f64

129

Bunu sadece read_csv()komutta farklı bir codec paketi tanımlayarak değiştirdim :

encoding = 'unicode_escape'

Örneğin:

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

1
Sadece kullanıyorsanızpandas
Valeriy

1
üzgünüm, bu işe yaramadı, yine aynı hatayla karşılaştım. ancak ('dosyaadı.csv', motor = 'python') kullandığımda. Bu işe yaradı.
basavaraj_S

117

Aşağıdaki kod snippet'ini deneyin:

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

7
Bunun ryerine vardı rb. hatırlatıcı eklemek için teşekkürler b!
Paul

1
Varsayılan olarak openişlev salt okunur mod olarak 'r' değerine sahiptir. rbikili modu okumak anlamına gelir.
shiva

39

asciiDizenizde kodlanmış karakter olmayan bir karakter var.

utf-8Kodunuzda başka kodlamalar kullanmanız gerekirse kodunu çözememeniz olabilir. Örneğin:

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

Bu durumda, kodlama windows-1252yapmanız gerekenlerdir:

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

Artık Unicodeelinizde, güvenle kodlayabilirsiniz utf-8.


1
Bazı beklenmedik "gizemli bayt" kodlama kurmak yardımcı olabilir basit bir sayfa oluşturduk; tripleee.github.io/8bit
tripleee

34

Okuma üzerinde csv, bir kodlama yöntemi eklendi:

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

16

Kodunuzun üst kısmındaki varsayılan kodlayıcıyı ayarlayın

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

Bence python3 sys modülünde setdefaultencoding yok!
Anwar Hossain

14

2018-05 itibariyle, bu decodeen azından Python 3 için doğrudan ele alınmaktadır .

Aşağıdaki snippet'i invalid start byteve invalid continuation byteyazım hatalarını kullanıyorum. Eklemek errors='ignore'benim için düzeltildi.

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

1
Tabii ki, bu sessizce bilgiyi atar. Daha iyi bir çözüm, orada ne olması gerektiğini bulmak ve orijinal sorunu düzeltmektir.
tripleee

14

@Aaronpenne ve @Soumyaansh'dan ilham alındı

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

"AttributeError: 'str' nesnesinin" decode "niteliği yok. Neyin yanlış gittiğinden emin değil misiniz?
Victor Wong

"Rb" ye b eklediniz mi? B, dosyayı bayt biçimli olarak açmak içindir. Sadece r kullanırsanız, dizedir ve kod çözme içermez.
Punnerud

14

Bu çözüm benim için çalıştı:

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

11

Basit Çözüm:

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

3
Bu yardımcı oldu teşekkürler!
Ruben

Yardım için sevindim @Ruben
Gil Baggio

2
Teşekkür ederim bu bana yardımcı oldu. Pandalar üzerinde çalışıyordum. Tekrar teşekkürler
basavaraj_S

Mutlu yardım @basavaraj_S
Gil Baggio

1
Burada sunulanların hepsi için çalışan tek çözüm.
lunesco

7

Aşağıdaki satır JSON kodlayıcısına zarar veriyor,

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

Bunun için geçici bir düzeltme aldım

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

Bunu geçici bir düzeltme olarak doğru olarak işaretleme (Emin değilim).


5

Yukarıdaki yöntemler işe yaramıyorsa, csv dosyasının kodlamasını kendiniz değiştirmek isteyebilirsiniz.

Excel'i kullanma:

  1. Excel kullanarak csv dosyasını açma
  2. "Dosya menüsü" seçeneğine gidin ve "Farklı Kaydet" i tıklayın
  3. Dosyayı kaydetmek için bir konum seçmek üzere "Gözat" ı tıklayın
  4. İstenen dosya adını girin
  5. CSV (Virgülle ayrılmış) (* .csv) seçeneğini belirtin
  6. "Araçlar" açılır kutusunu ve "Web Seçenekleri" ni tıklayın
  7. "Kodlama" sekmesi altında, "Bu dokümanı farklı kaydet" açılır listesinden Unicode (UTF-8) seçeneğini belirtin
  8. Dosya 'yı kaydet

Not Defteri'ni kullanma:

  1. Not defteri kullanarak csv dosyasını açın
  2. "Dosya"> "Farklı Kaydet" seçeneğine gidin
  3. Ardından, dosyanın konumunu seçin
  4. Kayıt türü seçeneğini Tüm Dosyalar ( . ) Olarak seçin .
  5. Dosya adını .csv uzantılı olarak belirtin
  6. "Kodlama" açılır listesinden UTF-8 seçeneğini belirleyin.
  7. Dosyayı kaydetmek için Kaydet'i tıklayın

Bunu yaparak, UnicodeCodeError ile karşılaşmadan csv dosyalarını içe aktarabilmelisiniz.


2

Yukarıda belirtilen tüm geçici çözümleri denedikten sonra yine de aynı hatayı atarsa, dosyayı CSV olarak dışa aktarmayı deneyebilirsiniz (zaten varsa ikinci kez). Özellikle scikit learn kullanıyorsanız, veri kümesini CSV dosyası olarak içe aktarmak en iyisidir.

Birlikte saatler geçirdim, ancak çözüm bu kadar basitti. Dosyayı CSV olarak Anaconda veya sınıflandırma araçlarınızın yüklü olduğu dizine aktarın ve deneyin.


2

Özel kullanım ve girişinizin standart kodlamasını kullanabilirsiniz.

utf-8 varsayılan değerdir.

iso8859-1 Batı Avrupa için de popülerdir.

Örneğin: bytes_obj.decode('iso8859-1')

bakınız: dokümanlar


1
Kodlamanın körü körüne tahmin edilmesi daha fazla hata üretebilir. Dosyanın hangi kodlamayı kullandığını bilmeden iso8859-1 veya cp1251 vb. Seçilmesi semptomu ortadan kaldırır, ancak yanlış tahmin ederseniz çöp üretir. Sadece birkaç bayt ise, gerçek hatayı fark edip düzeltmeniz yıllar alabilir .
tripleee

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.