2010-08-13 39 views
10

Tôi đang đọc trong tệp có mô-đun csv của Python và có Câu hỏi mã hóa khác (xin lỗi, có quá nhiều ở đây).Python csv: UnicodeDecodeError

Trong tệp CSV, có các dấu hiệu £. Sau khi đọc hàng và in nó, chúng đã trở thành \ xa3.

Đang cố gắng để mã hóa chúng như Unicode tạo ra một UnicodeDecodeError:

row = [unicode(x.strip()) for x in row] 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xa3 in position 0: ordinal not in range(128) 

Tôi đã được đọc csv documentation và rất nhiều những câu hỏi khác về vấn đề này trên StackOverflow. Tôi nghĩ rằng rằng £ trở thành \ xa3 trong ASCII có nghĩa là tệp CSV ban đầu ở dạng UTF-8.

(Ngẫu nhiên, là có một cách nhanh chóng để kiểm tra mã hóa về tệp CSV?)

Nếu đó là trong UTF-8, sau đó không nên module csv có thể để đối phó với nó? Dường như chuyển đổi tất cả các ký hiệu thành ASCII, mặc dù tài liệu cho rằng nó chấp nhận UTF-8.

Tôi đã thử thêm chức năng unicode_csv_reader như được mô tả trong csv examples, nhưng không hiệu quả.

---- CHỈNH SỬA -----

Tôi nên làm rõ một điều. Tôi đã thấy this question, trông rất giống nhau. Nhưng thêm unicode_csv_reader chức năng xác định có tạo ra một lỗi khác nhau thay vì:

yield [unicode(cell, 'utf-8') for cell in row] 
UnicodeDecodeError: 'utf8' codec can't decode byte 0xa3 in position 8: unexpected code byte 

Vì vậy, có lẽ tập tin của tôi không phải là UTF8 sau khi tất cả? Làm thế nào tôi có thể nói?

Trả lời

7

Hãy thử sử dụng "ISO-8859-1" để mã hóa của bạn. Có vẻ như bạn đang giao dịch với ASCII mở rộng, không phải Unicode.

Edit:

Dưới đây là một số mã đơn giản mà giao dịch với ASCII mở rộng:

>>> s = "La Pe\xf1a" 
>>> print s 
La Pe±a 
>>> print s.decode("latin-1") 
La Peña 
>>> 

Thậm chí tốt hơn, đối phó với các nhân vật chính xác mà là đem lại cho bạn những vấn đề:

>>> s = "12\xa3" 
>>> print s.decode("latin-1") 
12£ 
>>> 
+0

Bạn có nghĩa là sử dụng: năng suất [unicode (di động, 'tiêu chuẩn ISO-8859-1') cho các tế bào trong hàng] thay vào đó, trong hàm unicode_csv_reader? Thật không may mà không giúp đỡ - trở lại lỗi thứ tự không trong phạm vi (128) một lần nữa. – AP257

+0

Sẽ không có ý nghĩa gì khi sử dụng hàm unicode() khi giao dịch với ASCII. Những gì tôi đang nói là bạn đang đối phó với một tập tin được mã hóa bằng cách sử dụng một mã hóa "ISO-8859-1".Tôi đã không đăng bất kỳ mã nào, bởi vì tôi không biết làm thế nào để làm điều đó ra khỏi đỉnh đầu của tôi, nhưng vấn đề của bạn là bạn cần phải giải mã nó như là ISO-8859-1, không phải Unicode. – riwalk

+0

OK, cảm ơn. Tôi sẽ điều tra. Làm thế nào bạn biết nó là ISO-8859-1? Nói cách khác, có cách nào để tôi kiểm tra mã hóa bản thân mình, thay vì chỉ hỏi những câu hỏi ngu ngốc trên StackOverflow :) – AP257

0

Nếu bạn là trên Windows, rất có khả năng rằng mã hóa mà bạn nên sử dụng là một trong những gia đình cp125X ... ví dụ nếu bạn ở Tây Âu hoặc Châu Mỹ, nó sẽ là cp1252. Phần mềm Windows thường sử dụng các byte trong phạm vi \x80 đến \x9F bao gồm để mã hóa các ký tự dấu câu ưa thích trong khi phạm vi đó được đặt trong ISO-8859-X đối với "Ký tự điều khiển C1" hiếm khi được sử dụng.

Bạn có thể tìm hiểu mã hóa bình thường trong miền địa phương của bạn bằng cách chạy này tại cửa sổ dòng lệnh:

python -c "import locale; print locale.getpreferredencoding()" 
+0

Anh ấy gặp khó khăn khi đọc bảng hiệu, và bạn cho rằng tệp được lưu thuận tiện trên mọi cài đặt * máy tính * của anh ấy thích? Tôi sẽ cẩn thận làm cho giả định rằng tập tin là một cái gì đó đã được lưu bằng cách sử dụng máy tính của mình. – riwalk

+0

@ Stargazer712: Không, tôi không giả định gì cả. Tôi cho rằng rất có khả năng tệp được tạo trên một máy tính trong cùng một miền địa phương và sử dụng cùng một hệ điều hành với máy mà OP đang sử dụng. –

+0

Trải nghiệm của tôi với mã hóa (như tôi đã đề cập trước đó) đến từ việc cào web. Tôi đảm bảo với bạn nó không phải là một giả định an toàn. – riwalk

Các vấn đề liên quan