2012-01-07 42 views
5

Tôi đang cố gửi yêu cầu POST tới ứng dụng web. Tôi đang sử dụng mô-đun cơ giới hóa (chính nó là một wrapper của urllib2). Dù sao, khi tôi cố gửi yêu cầu POST, tôi nhận được UnicodeDecodeError: 'ascii' codec can't decode byte 0xc5 in position 0: ordinal not in range(128). Tôi đã thử đưa các unicode(string), các unicode(string, encoding="utf-8"), unicode(string).encode() vv, không có gì làm việc - hoặc trả lại lỗi trên, hoặc TypeError: decoding Unicode is not supportedGửi yêu cầu POST không phải ASCII bằng Python?

Tôi nhìn SO câu trả lời khác cho những câu hỏi tương tự, nhưng không ai giúp đỡ.

Cảm ơn trước!

EDIT: Ví dụ sản xuất một lỗi:

prda = "šđćč" #valid UTF-8 characters 
prda # typing in python shell 
'\xc5\xa1\xc4\x91\xc4\x87\xc4\x8d' 
print prda # in shell 
šđćč 
prda.encode("utf-8") #in shell 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc5 in position 0: ordinal not in range(128) 
unicode(prda) 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc5 in position 0: ordinal not in range(128) 
+0

Tôi sẽ trợ giúp nếu bạn cho thấy một ví dụ nhỏ, khép kín tạo ra lỗi. – ekhumoro

+0

@ekhumoro thêm ví dụ, hy vọng nó xóa nó lên –

Trả lời

7

Tôi giả sử bạn đang sử dụng Python 2.x.

Cho một đối tượng unicode:

myUnicode = u'\u4f60\u597d' 

mã hóa nó bằng cách sử utf-8:

mystr = myUnicode.encode('utf-8') 

Lưu ý rằng bạn cần phải xác định mã hóa một cách rõ ràng. Theo mặc định nó sẽ (thường) sử dụng ascii.

+0

Cảm ơn bạn đã trả lời. Làm thế nào tôi sẽ đi về việc chuyển đổi nó thành một đối tượng unicode nếu tôi có một biến chuỗi (thay vì chuỗi)? Nó được chôn sâu vào mã để tôi chỉ cần thêm tiền tố 'u'' trước khi biến chuỗi được gán. –

0

Bạn không cần phải quấn chars của bạn trong unicode cuộc gọi, bởi vì họ đang đã được mã hóa :) nếu bất cứ điều gì, bạn cần phải DE -code nó để có được một đối tượng unicode:

>>> s = '\xc5\xa1\xc4\x91\xc4\x87\xc4\x8d' # your string 
>>> s.decode('utf-8') 
u'\u0161\u0111\u0107\u010d' 
>>> type(s.decode('utf-8')) 
<type 'unicode'> 

Tôi không biết mechanize vì vậy tôi không biết chính xác liệu nó có xử lý đúng hay không, tôi sợ.

Những gì tôi muốn làm với một thường xuyên urllib2 gọi POST, sẽ được sử dụng urlencode:

>>> from urllib import urlencode 
>>> postData = urlencode({'test': s }) # note I'm NOT decoding it 
>>> postData 
'test=%C5%A1%C4%91%C4%87%C4%8D' 
>>> urllib2.urlopen(url, postData) # etc etc etc 
1

Trong ví dụ của bạn, bạn sử dụng một chuỗi không unicode đen có chứa các ký tự không ascii, mà kết quả trong prda trở thành một chuỗi byte.

Để đạt được điều này, python sử dụng sys.stdin.encoding để tự động mã hóa chuỗi. Trong trường hợp của bạn, điều này có nghĩa là chuỗi được mã hóa là "utf-8".

Để chuyển đổi prda đến một unicode đối tượng, bạn cần phải giải mã nó bằng cách sử dụng mã hóa thích hợp:

>>> print prda.decode('utf-8') 
šđćč 

Lưu ý rằng, trong một kịch bản hoặc mô-đun, bạn không thể dựa vào python để tự động đoán mã hóa - bạn sẽ cần xóa mã hóa ở đầu tệp như một cách rõ ràng, như sau:

# -*- coding: utf-8 -*- 

Bất cứ khi nào bạn gặp phải lỗi unicode trong Python 2, thường là vì mã của bạn là trộn chuỗi byte với chuỗi unicode. Vì vậy, bạn nên luôn kiểm tra loại chuỗi nào gây ra lỗi, bằng cách sử dụng type(string).

Nếu đối tượng chuỗi là <type 'str'>, nhưng bạn cần unicode, giải mã bằng mã hóa thích hợp. Nếu đối tượng chuỗi là <type 'unicode'>, nhưng bạn cần byte, mã hóa bằng cách sử dụng mã hóa thích hợp.

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