2011-01-10 17 views
6

Tôi đã đọc tất cả các câu hỏi liên quan đến chuyển đổi từ Unicode sang CSV bằng Python ở đây trong StackOverflow và tôi vẫn bị mất. Mỗi lần tôi nhận được một "UnicodeEncodeError: 'ascii' codec không thể mã hóa kí tự u '\ xd1' ở vị trí 12: thứ tự không trong phạm vi (128)"Python: Chuyển đổi Unicode thành ASCII mà không có lỗi cho tệp CSV

buffer=cStringIO.StringIO() 
writer=csv.writer(buffer, csv.excel) 
cr.execute(query, query_param) 
while (1): 
    row = cr.fetchone() 
    writer.writerow([s.encode('ascii','ignore') for s in row]) 

Giá trị của hàng

(56, u"LIMPIADOR BA\xd1O 1'5 L") 

trong đó giá trị của \ xd10 tại cơ sở dữ liệu là ñ, một dấu có dấu phụ được sử dụng bằng tiếng Tây Ban Nha. Lúc đầu, tôi đã cố gắng chuyển đổi giá trị thành một cái gì đó hợp lệ trong ascii, nhưng sau khi mất quá nhiều thời gian, tôi chỉ cố gắng bỏ qua những ký tự đó (tôi cho rằng tôi có cùng một vấn đề với các nguyên âm có dấu).

Tôi muốn lưu giá trị vào CSV, tốt nhất là với - ("LIMPIADOR BAÑO 1'5 L"), nhưng nếu không thể, ít nhất có thể lưu nó ("LIMPIADOR BAO 1'5 L ").

+0

Câu hỏi của bạn là gì? –

+0

Đã cập nhật với câu hỏi ở cuối. – Sergi

+1

Tại sao bạn không thử mã hóa vào trang mã 'ANSI' của Windows? Tôi đoán bạn đang sử dụng Windows vì CSV thường được sử dụng nhất trên Windows, nhưng hãy bỏ qua tôi nếu điều này là rộng của nhãn hiệu. Trên hệ điều hành * NIX, tôi đoán một trong các mã hóa ISO 8 bit sẽ phù hợp, nhưng tôi không có chuyên gia. –

Trả lời

12

Đúng, ñ không phải là ký tự ASCII hợp lệ, vì vậy bạn không thể mã hóa nó thành ASCII. Vì vậy, bạn có thể, như mã của bạn làm ở trên, bỏ qua chúng. Một cách khác, cụ thể là để xóa dấu trọng âm, bạn có thể tìm thấy ở đây: What is the best way to remove accents in a Python unicode string?

Nhưng lưu ý rằng cả hai kỹ thuật đều có thể gây ảnh hưởng xấu, như cách viết thực sự có ý nghĩa khác, v.v. Tốt nhất là giữ dấu. Và sau đó bạn không thể sử dụng ASCII, nhưng bạn có thể sử dụng mã hóa khác. UTF-8 là cược an toàn. Latin-1 hoặc ISO-88591-1 là phổ biến nhất, nhưng nó chỉ bao gồm các ký tự Tây Âu. CP-1252 phổ biến trên Windows, v.v.,

Vì vậy, chỉ cần chuyển "ascii" cho bất kỳ mã hóa nào bạn muốn.


mã thực tế của bạn, theo nhận xét của bạn là:

writer.writerow([s.encode('utf8') if type(s) is unicode else s for s in row]) 

nơi

row = (56, u"LIMPIADOR BA\xd1O 1'5 L") 

Bây giờ, tôi tin rằng sẽ làm việc, nhưng dường như nó không. Tôi nghĩ rằng unicode được thông qua vào nhà văn cvs do nhầm lẫn anyway. Bỏ liên kết dài dòng đó với các phần của nó:

col1, col2 = row # Use the names of what is actually there instead 
row = col1, col2.encode('utf8') 
writer.writerow(row) 

Bây giờ, lỗi thực sự của bạn sẽ không bị ẩn bởi thực tế bạn dính mọi thứ vào cùng một dòng. Điều này cũng có thể đã tránh được nếu bạn đã bao gồm một traceback thích hợp.

+0

Hầu hết người đọc CSV không thể xử lý UTF-8. CSV thường được đọc trên Windows và do đó một trong những mã hóa ANSI được gọi là có vẻ thích hợp nhất. –

+0

Vâng, tôi không biết về "nhất", nhưng một số ít nhất. Và CSV được sử dụng ở mọi nơi. Rõ ràng một mã hóa có thể được đọc bởi phần mềm đích cần được sử dụng. –

+0

Điều này là mã trên, sử dụng chuỗi unicode u "LIMPIADOR BA \ xd1O 1'5 L" thất bại thảm hại với lỗi UnicodeEncodeError cũng được nêu chi tiết ở trên (cờ "bỏ qua" không hoạt động, tôi không biết tại sao) .Trong điều kiện lý tưởng, tôi muốn lấy một tập tin CSV với chuỗi đầy đủ, bao gồm cả các. – Sergi