UnicodeDecodeError ไบต์ต่อเนื่องที่ไม่ถูกต้อง


257

ทำไมรายการด้านล่างจึงล้มเหลว และทำไมถึงประสบความสำเร็จกับ "latin-1" codec

o = "a test of \xe9 char" #I want this to remain a string as this is what I am receiving
v = o.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 0xe9 in position 10: invalid continuation byte

คำตอบ:


247

ในไบนารี 0xE9 1110 1001ดูเหมือนว่า ถ้าคุณอ่านเกี่ยวกับUTF-8 ในวิกิพีเดีย , 10xx xxxxคุณจะเห็นว่าไบต์ดังกล่าวจะต้องตามมาด้วยสองของแบบฟอร์ม ตัวอย่างเช่น:

>>> b'\xe9\x80\x80'.decode('utf-8')
u'\u9000'

แต่นั่นเป็นเพียงสาเหตุเชิงกลของข้อยกเว้น ในกรณีนี้คุณมีสตริงที่เข้ารหัสเกือบเป็นลาติน 1 คุณสามารถดูว่า UTF-8 และละติน 1 มีลักษณะอย่างไร:

>>> u'\xe9'.encode('utf-8')
b'\xc3\xa9'
>>> u'\xe9'.encode('latin-1')
b'\xe9'

(หมายเหตุฉันกำลังใช้การผสมผสานของ Python 2 กับ 3 ที่นี่การป้อนข้อมูลนั้นใช้ได้ใน Python ทุกรุ่น แต่ Python interpreter ของคุณไม่น่าจะแสดงสตริง unicode และไบต์แบบนี้)


2
ขอบคุณ (และคนอื่น ๆ ที่ตอบกลับ) ฉันอยู่ภายใต้ความเชื่อที่ผิดที่ตัวอักษรจนถึง 255 จะแปลงโดยตรง
RuiDC

ฉันได้รับUnicodeEncodeError: 'ascii' codec can't encode characters in position 2-3: ordinal not in range(128)ข้อผิดพลาดในการใช้.encode(latin-1)
Shiva

235

ฉันมีข้อผิดพลาดเดียวกันเมื่อฉันพยายามเปิดไฟล์ csv โดยวิธี pandas read_csv

วิธีแก้ไขคือเปลี่ยนการเข้ารหัสเป็น 'latin-1':

pd.read_csv('ml-100k/u.item', sep='|', names=m_cols , encoding='latin-1')

1
สิ่งนี้แก้ปัญหาได้จริงหรือไม่? มันไม่เพียงบอกแพนด้าให้ละเว้นไบต์ด้วยการลดระดับเป็นรูปแบบการเข้ารหัสที่ซับซ้อนน้อยลงหรือไม่
Yu Chen

61

มันไม่ถูกต้อง UTF-8 ตัวอักษรนั้นเป็นตัวอักษรอิเล็กทรอนิกส์ใน ISO-Latin1 ซึ่งเป็นสาเหตุว่าทำไมจึงประสบความสำเร็จกับชุดรหัสนั้น

หากคุณไม่ทราบชุดรหัสที่คุณได้รับสตริงแสดงว่าคุณมีปัญหาเล็กน้อย มันจะเป็นการดีที่สุดถ้าเลือกชุดรหัสเดียว (หวังว่า UTF-8) สำหรับโปรโตคอล / แอปพลิเคชันของคุณและจากนั้นคุณเพียงแค่ปฏิเสธรหัสที่ไม่ได้ถอดรหัส

หากคุณไม่สามารถทำเช่นนั้นได้คุณจะต้องมีการวิเคราะห์พฤติกรรม


2
และสำหรับฮิวริสติกดูห้องสมุด chardet
mlissner

44

เนื่องจาก UTF-8 เป็นมัลติไบต์และไม่มีอักขระที่สอดคล้องกับชุดของคุณ \xe9พื้นที่บวกต่อไปนี้ของคุณ

เหตุใดจึงควรประสบความสำเร็จทั้งในutf-8 และ latin-1

นี่คือวิธีที่ประโยคเดียวกันควรอยู่ใน utf-8:

>>> o.decode('latin-1').encode("utf-8")
'a test of \xc3\xa9 char'

Latin-1 เป็นตระกูลการเข้ารหัสไบต์เดียวดังนั้นทุกอย่างในนั้นควรถูกกำหนดใน UTF-8 แต่ทำไมละติน -1 ถึงชนะบ้าง?
Reihan_amn

11

หากข้อผิดพลาดนี้เกิดขึ้นเมื่อจัดการไฟล์ที่เพิ่งเปิดให้ตรวจสอบเพื่อดูว่าคุณเปิดใน'rb'โหมด


2
ขอบคุณคำตอบนี้สามารถหลีกเลี่ยงข้อผิดพลาด UnicodeDecodeError: ตัวแปลงสัญญาณ 'utf-8' ไม่สามารถถอดรหัสไบต์ 0xd7 ในตำแหน่ง 2024079: ไบต์ต่อเนื่องที่ไม่ถูกต้อง โดย soup = BeautifulSoup(open('webpage.html', 'rb'), 'html.parser')
Isaac Philip

6

เรื่องนี้เกิดขึ้นกับฉันในขณะที่ฉันกำลังอ่านข้อความที่มีฮิบรูจาก.txtไฟล์

ฉันคลิก: file -> save asและฉันบันทึกไฟล์นี้เป็นการUTF-8เข้ารหัส


5

ข้อผิดพลาดของรหัส utf-8 มักเกิดขึ้นเมื่อช่วงของค่าตัวเลขเกิน 0 ถึง 127

เหตุผลที่ยกข้อยกเว้นนี้คือ:

1) ถ้าจุดรหัสเป็น <128 แต่ละไบต์จะเหมือนกันกับค่าของจุดรหัส 2) หากจุดรหัสเป็น 128 หรือสูงกว่าสตริง Unicode จะไม่สามารถแสดงในการเข้ารหัสนี้ได้ (Python ทำให้เกิดข้อยกเว้น UnicodeEncodeError ในกรณีนี้)

เพื่อที่จะเอาชนะสิ่งนี้เรามีชุดการเข้ารหัสที่ใช้กันอย่างแพร่หลายที่สุดคือ "Latin-1 หรือที่เรียกว่า ISO-8859-1"

ดังนั้น ISO-8859-1 Unicode points 0–255 จึงเหมือนกับค่า Latin-1 ดังนั้นการแปลงเป็นการเข้ารหัสนี้เพียงแค่ต้องการการแปลงจุดโค้ดเป็นค่าไบต์ หากพบจุดโค้ดที่มากกว่า 255 สตริงจะไม่สามารถเข้ารหัสเป็น Latin-1 ได้

เมื่อข้อยกเว้นนี้เกิดขึ้นเมื่อคุณพยายามโหลดชุดข้อมูลลองใช้รูปแบบนี้

df=pd.read_csv("top50.csv",encoding='ISO-8859-1')

เพิ่มเทคนิคการเข้ารหัสที่ส่วนท้ายของไวยากรณ์ซึ่งยอมรับการโหลดชุดข้อมูล


สวัสดีและยินดีต้อนรับสู่ SO! โปรดแก้ไขคำตอบของคุณเพื่อให้แน่ใจว่าจะได้รับการปรับปรุงตามคำตอบอื่น ๆ ที่มีอยู่แล้วในคำถามนี้
hongsy


0

ข้อผิดพลาดประเภทนี้เกิดขึ้นเมื่อคุณกำลังรับไฟล์หรือข้อมูลเฉพาะในแพนด้าเช่น: -

data=pd.read_csv('/kaggle/input/fertilizers-by-product-fao/FertilizersProduct.csv)

ดังนั้นข้อผิดพลาดจะแสดงดังนี้: - UnicodeDecodeError: ตัวแปลงสัญญาณ 'utf-8' ไม่สามารถถอดรหัสไบต์ 0xf4 ในตำแหน่ง 1: ไบต์ต่อเนื่องที่ไม่ถูกต้อง

ดังนั้นเพื่อหลีกเลี่ยงข้อผิดพลาดประเภทนี้สามารถลบออกได้โดยการเพิ่มอาร์กิวเมนต์

data=pd.read_csv('/kaggle/input/fertilizers-by-product-fao/FertilizersProduct.csv', encoding='ISO-8859-1')

โปรดจัดรูปแบบรหัสของคุณอย่างถูกต้องคลิกที่นี่เพื่อเรียนรู้วิธี
БогданОпир

-1

ในกรณีนี้ฉันพยายามรัน. py ซึ่งใช้งาน path / file.sql

วิธีแก้ปัญหาของฉันคือแก้ไข codification ของ file.sql เป็น "UTF-8 without BOM" และใช้งานได้!

คุณสามารถทำได้ด้วย Notepad ++

ฉันจะปล่อยให้ส่วนหนึ่งของรหัสของฉัน

/ รหัส /

con = psycopg2.connect (โฮสต์ = sys.argv [1], พอร์ต = sys.argv [2], dbname = sys.argv [3], ผู้ใช้ = sys.argv [4], รหัสผ่าน = sys.argv [5] )

เคอร์เซอร์ = con.cursor () sqlfile = เปิด (เส้นทาง, 'r')

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