UnicodeDecodeError: ตัวแปลงสัญญาณ 'utf8' ไม่สามารถถอดรหัสไบต์ 0xa5 ในตำแหน่ง 0: ไบต์เริ่มต้นที่ไม่ถูกต้อง


188

ฉันใช้Python-2.6 CGIสคริปต์ แต่ไม่พบข้อผิดพลาดในการเข้าสู่ระบบเซิร์ฟเวอร์ในขณะที่ทำ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

ที่นี่

​__get​data()dictionary {}กลับมาทำงาน

ก่อนที่จะโพสต์คำถามนี้ฉันได้เรียกคำถามนี้ว่าระบบปฏิบัติการดังนั้น


การปรับปรุง

บรรทัดต่อไปนี้สร้างความเสียหายให้กับตัวเข้ารหัส 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

ฉันได้รับการแก้ไขชั่วคราวสำหรับมัน

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

แต่ฉันไม่แน่ใจว่าเป็นวิธีที่ถูกต้องหรือไม่


1
ดูเหมือนว่าคุณมีข้อมูลสตริงในพจนานุกรมที่ไม่สามารถเข้ารหัส / ถอดรหัส มีอะไรในdict?
mgilson

@ mgilson yup master ฉันเข้าใจปัญหา แต่ donno วิธีจัดการกับมัน .. dictมีlist, dict, python timestamp value
Deepak Ingole

1
@Pilot - ไม่จริง __getdataปัญหาที่แท้จริงถูกฝังอยู่ที่ไหนสักแห่งใน ฉันไม่รู้ว่าทำไมคุณถึงได้เป็นตัวละครที่ไม่สามารถถอดรหัสได้ คุณสามารถลองหาแผ่นแปะบน dict เพื่อใช้งานได้ แต่ส่วนใหญ่นั้นจะขอปัญหาเพิ่มเติมในภายหลัง ฉันจะลองพิมพ์พจน์เพื่อดูว่าตัวละครที่ไม่ใช่ ASCII อยู่ที่ไหน จากนั้นหาวิธีที่เขตข้อมูลนั้นคำนวณ / ตั้งค่าและทำงานย้อนกลับจากตรงนั้น
mgilson


1
ฉันมีข้อผิดพลาดเดียวกันนี้เมื่อพยายามอ่านไฟล์. csv ซึ่งมีอักขระที่ไม่ใช่ ASCII บางตัวอยู่ การลบอักขระเหล่านั้น (ตามที่แนะนำด้านล่าง) แก้ไขปัญหาได้
Dmitriy R. Starson

คำตอบ:


87

ข้อผิดพลาดคือเนื่องจากมีอักขระที่ไม่ใช่ ASCII บางตัวในพจนานุกรมและไม่สามารถเข้ารหัส / ถอดรหัสได้ วิธีง่ายๆในการหลีกเลี่ยงข้อผิดพลาดนี้คือการเข้ารหัสสตริงดังกล่าวด้วยencode()ฟังก์ชั่นดังต่อไปนี้ (ถ้าaเป็นสตริงที่มีอักขระที่ไม่ใช่ ASCII):

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

2
เนื่องจาก UTF-8 เข้ากันได้กับ ASCII 7 บิตแบบเก่าคุณจึงควรเข้ารหัสทุกอย่าง สำหรับตัวละครในช่วง ASCII 7 บิตการเข้ารหัสนี้จะเป็นการจับคู่ข้อมูลเฉพาะตัว
Tadeusz A. Kadłubowski

29
ดูเหมือนจะไม่ชัดเจนจริง เมื่อนำเข้าไฟล์ csv คุณจะใช้รหัสนี้อย่างไร
เดฟ

ปัญหาเดียวกันปรากฏขึ้นสำหรับฉันเมื่อเรียกใช้งานแบบสอบถาม sqlalchemy ฉันจะเข้ารหัสแบบสอบถามได้อย่างไร (ไม่มีรหัส. เนื่องจากไม่ใช่สตริง)
c8999c 3f964f64

129

ฉันเปลี่ยนสิ่งนี้โดยการกำหนดแพ็คเกจ codec อื่นในread_csv()คำสั่ง:

encoding = 'unicode_escape'

เช่น:

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

1
เฉพาะในกรณีที่คุณใช้pandas
Valeriy

1
ขออภัยนี่ไม่ทำงานฉันมีข้อผิดพลาดเดียวกันอีกครั้ง แต่เมื่อฉันใช้ ('filename.csv', engine = 'python') สิ่งนี้ใช้ได้ผล
basavaraj_S

117

ลองตัวอย่างโค้ดด้านล่าง:

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

7
ฉันมีแทนr rbขอบคุณสำหรับคำเตือนให้เพิ่มb!
พอล

1
โดยopenฟังก์ชั่นเริ่มต้นมี 'r' เป็นโหมดอ่านอย่างเดียว rbหมายถึงอ่านโหมดไบนารี
พระอิศวร

39

สตริงของคุณมีการasciiเข้ารหัสอักขระที่ไม่ใช่

การไม่สามารถถอดรหัสด้วยutf-8อาจเกิดขึ้นหากคุณต้องการใช้การเข้ารหัสอื่น ๆ ในรหัสของคุณ ตัวอย่างเช่น:

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

ในกรณีนี้การเข้ารหัสคือwindows-1252สิ่งที่คุณต้องทำ:

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

ตอนนี้คุณมีUnicode, utf-8คุณสามารถเข้ารหัสเข้า


1
ฉันได้สร้างหน้าง่าย ๆ ซึ่งอาจช่วยสร้างการเข้ารหัสของ "มิสทรี้ไบต์" ที่ไม่คาดคิดบางอย่าง; tripleee.github.io/8bit
tripleee

34

เมื่ออ่านcsvฉันได้เพิ่มวิธีการเข้ารหัส:

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

16

ตั้งค่าตัวเข้ารหัสเริ่มต้นที่ด้านบนของรหัสของคุณ

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

ฉันคิดว่า python3 ไม่มีการตั้งค่าเริ่มต้นการเข้ารหัสในโมดูล sys!
Anwar Hossain

14

ในฐานะของ 2018-05 นี้จะถูกจัดการโดยตรงกับdecodeอย่างน้อยสำหรับหลาม 3

ฉันกำลังใช้ข้อมูลโค้ดด้านล่างสำหรับinvalid start byteและinvalid continuation byteพิมพ์ข้อผิดพลาด การเพิ่มerrors='ignore'แก้ไขให้ฉัน

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

1
แน่นอนว่านี่เป็นการละทิ้งข้อมูลอย่างเงียบ ๆ การแก้ไขที่ดีกว่ามากคือการค้นหาว่าควรจะมีอะไรและแก้ไขปัญหาเดิม
tripleee

14

แรงบันดาลใจจาก @aaronpenne และ @Soumyaansh

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

ฉันได้รับ "AttributeError: 'str' วัตถุไม่มีแอตทริบิวต์ 'ถอดรหัส'" ไม่แน่ใจว่ามีอะไรผิดพลาดหรือ
วิกเตอร์หว่อง

คุณรวม b ถึง "rb" หรือไม่? b คือการเปิดไฟล์ในรูปแบบไบต์ หากคุณเพียงแค่ใช้ r มันเป็นสตริงและไม่รวมถอดรหัส
Punnerud


11

วิธีแก้ปัญหาง่าย ๆ :

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

3
ขอบคุณที่ช่วย!
รูเบน

ดีใจที่ได้ช่วยเหลือ @Ruben
Gil Baggio

2
ขอบคุณสิ่งนี้ช่วยฉัน ฉันทำงานกับแพนด้า ขอขอบคุณอีกครั้ง
basavaraj_S

ยินดีที่จะช่วย @basavaraj_S
Gil Baggio

1
ทางออกเดียวที่เหมาะกับฉันของทั้งหมดที่นำเสนอที่นี่
lunesco

7

บรรทัดต่อไปนี้สร้างความเสียหายให้กับตัวเข้ารหัส 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

ฉันได้รับการแก้ไขชั่วคราวสำหรับมัน

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

ทำเครื่องหมายว่าถูกต้องเป็นการแก้ไขชั่วคราว (ไม่แน่ใจ)


5

หากวิธีการข้างต้นไม่ได้ผลสำหรับคุณคุณอาจต้องการเปลี่ยนการเข้ารหัสไฟล์ csv เอง

ใช้ Excel:

  1. เปิดไฟล์ csv โดยใช้ Excel
  2. ไปที่ตัวเลือก "เมนูไฟล์" แล้วคลิก "บันทึกเป็น"
  3. คลิก "เรียกดู" เพื่อเลือกตำแหน่งที่จะบันทึกไฟล์
  4. ป้อนชื่อไฟล์ที่ต้องการ
  5. เลือกตัวเลือก CSV (คั่นด้วยเครื่องหมายจุลภาค) (* .csv)
  6. คลิกกล่อง "เครื่องมือ" แบบหล่นลงและคลิก "ตัวเลือกเว็บ"
  7. ภายใต้แท็บ "การเข้ารหัส" เลือกตัวเลือก Unicode (UTF-8) จาก "บันทึกเอกสารนี้เป็น" รายการแบบหล่นลง
  8. บันทึกไฟล์

ใช้ Notepad:

  1. เปิดไฟล์ csv โดยใช้ notepad
  2. ไปที่ตัวเลือก "ไฟล์"> "บันทึกเป็น"
  3. ถัดไปเลือกตำแหน่งของไฟล์
  4. เลือกตัวเลือกบันทึกเป็นประเภทเป็นไฟล์ทั้งหมด ( . )
  5. ระบุชื่อไฟล์ด้วยนามสกุล. csv
  6. จากรายการแบบเลื่อนลง "การเข้ารหัส" เลือกตัวเลือก UTF-8
  7. คลิกบันทึกเพื่อบันทึกไฟล์

โดยการทำเช่นนี้คุณควรจะสามารถนำเข้าไฟล์ csv โดยไม่พบ UnicodeCodeError


2

หลังจากลองวิธีแก้ปัญหาข้างต้นทั้งหมดแล้วหากยังคงมีข้อผิดพลาดเดิมอยู่คุณสามารถลองส่งออกไฟล์เป็น CSV (ครั้งที่สองถ้าคุณมีอยู่แล้ว) โดยเฉพาะถ้าคุณใช้ scikit เรียนรู้วิธีที่ดีที่สุดในการนำเข้าชุดข้อมูลเป็นไฟล์ CSV

ฉันใช้เวลาหลายชั่วโมงด้วยกันในขณะที่วิธีแก้ปัญหานี้ง่าย ส่งออกไฟล์เป็น CSV ไปยังไดเรกทอรีที่ติดตั้ง Anaconda หรือเครื่องมือตัวจําแนกของคุณและลอง


2

คุณสามารถใช้การเข้ารหัสมาตรฐานของการใช้งานเฉพาะและการป้อนข้อมูลของคุณ

utf-8 เป็นค่าเริ่มต้น

iso8859-1 ยังเป็นที่นิยมสำหรับยุโรปตะวันตก

เช่น: bytes_obj.decode('iso8859-1')

ดู: เอกสาร


1
การเดาการเข้ารหัสแบบสุ่มอาจทำให้เกิดข้อผิดพลาดเพิ่มขึ้น การเลือก iso8859-1 หรือ cp1251 ฯลฯ โดยไม่ทราบว่าการเข้ารหัสไฟล์ที่ใช้จะลบอาการ แต่สร้างขยะหากคุณเดาผิด หากเป็นเพียงไม่กี่ไบต์อาจใช้เวลาหลายปีกว่าที่คุณจะสังเกตเห็นและแก้ไขข้อผิดพลาดจริง
tripleee

0

แทนที่จะค้นหาวิธีถอดรหัส a5 (Yen ¥) หรือ 96 (en-dash ) บอก MySQL ว่าไคลเอนต์ของคุณถูกเข้ารหัส "latin1" แต่คุณต้องการ "utf8" ในฐานข้อมูล

ดูรายละเอียดในTrouble with UTF-8 ตัวอักษร; สิ่งที่ฉันเห็นไม่ใช่สิ่งที่ฉันเก็บไว้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.