2012-04-14 17 views
8

Tôi cố gắng để gửi dữ liệu unicode với httplib.request chức năng:Làm cách nào để đăng ký tự unicode bằng cách sử dụng httplib?

s = u"עברית" 
data = """ 
<spellrequest textalreadyclipped="0" ignoredups="1" ignoredigits="1" ignoreallcaps="0"> 
<text>%s</text> 
</spellrequest> 
""" % s 

con = httplib.HTTPSConnection("www.google.com") 
con.request("POST", "/tbproxy/spell?lang=he", data) 
response = con.getresponse().read() 

Tuy nhiên đây là lỗi của tôi:

Traceback (most recent call last): 
    File "C:\Scripts\iQuality\test.py", line 47, in <module> 
    print spellFix(u"╫á╫נ╫¿╫ץ╫ר╫ץ") 
    File "C:\Scripts\iQuality\test.py", line 26, in spellFix 
    con.request("POST", "/tbproxy/spell?lang=%s" % lang, data) 
    File "C:\Python27\lib\httplib.py", line 955, in request 
    self._send_request(method, url, body, headers) 
    File "C:\Python27\lib\httplib.py", line 989, in _send_request 
    self.endheaders(body) 
    File "C:\Python27\lib\httplib.py", line 951, in endheaders 
    self._send_output(message_body) 
    File "C:\Python27\lib\httplib.py", line 815, in _send_output 
    self.send(message_body) 
    File "C:\Python27\lib\httplib.py", line 787, in send 
    self.sock.sendall(data) 
    File "C:\Python27\lib\ssl.py", line 220, in sendall 
    v = self.send(data[count:]) 
    File "C:\Python27\lib\ssl.py", line 189, in send 
    v = self._sslobj.write(data) 
UnicodeEncodeError: 'ascii' codec can't encode characters in position 97-102: or 
dinal not in range(128) 

Tôi đang ở đâu vậy?

Trả lời

9

http không được xác định bằng mã hóa ký tự cụ thể và thay vào đó sử dụng octet. Bạn cần phải chuyển đổi dữ liệu của bạn thành một mã hóa, và sau đó bạn cần phải nói cho máy chủ mà mã hóa bạn đã sử dụng. Cho phép sử dụng utf8, vì đây thường là lựa chọn tốt nhất:

Dữ liệu này trông hơi giống XML nhưng bạn đang bỏ qua thẻ xml. Một số dịch vụ có thể chấp nhận điều đó, nhưng bạn không nên sao chép. Trong thực tế, mã hóa thực sự thuộc về đó; vì vậy hãy chắc chắn bạn bao gồm nó. Tiêu đề trông giống như <?xml version="1.0" encoding="mã hóa"?>.

s = u"עברית" 
data_unicode = u"""<?xml version="1.0" encoding="UTF-8"?> 
<spellrequest textalreadyclipped="0" ignoredups="1" ignoredigits="1" ignoreallcaps="0"> 
<text>%s</text> 
</spellrequest> 
""" % s 

data_octets = data_unicode.encode('utf-8') 

Như một vấn đề của lịch sự, bạn cũng nên nói với máy chủ bản thân định dạng và mã hóa, với content-type tiêu đề:

con = httplib.HTTPSConnection("www.google.com") 
con.request("POST", 
      "/tbproxy/spell?lang=he", 
      data_octets, {'content-type': 'text/xml; charset=utf-8'}) 

EDIT: Đó là làm việc tốt trên máy tính của tôi, bạn có chắc bạn 'không bỏ qua một cái gì đó? ví dụ đầy đủ

>>> from cgi import escape 
>>> from urllib import urlencode 
>>> import httplib 
>>> 
>>> template = u"""<?xml version="1.0" encoding="UTF-8"?> 
... <spellrequest textalreadyclipped="0" ignoredups="1" ignoredigits="1" ignoreallcaps="0"> 
... <text>%s</text> 
... </spellrequest> 
... """ 
>>> 
>>> def chkspell(word, lang='en'): 
...  data_octets = (template % escape(word)).encode('utf-8') 
...  con = httplib.HTTPSConnection("www.google.com") 
...  con.request("POST", 
...   "/tbproxy/spell?" + urlencode({'lang': lang}), 
...   data_octets, 
...   {'content-type': 'text/xml; charset=utf-8'}) 
...  req = con.getresponse() 
...  return req.read() 
... 
>>> chkspell('baseball') 
'<?xml version="1.0" encoding="UTF-8"?><spellresult error="0" clipped="0" charschecked="8"></spellresult>' 
>>> chkspell(corpus, 'he') 
'<?xml version="1.0" encoding="UTF-8"?><spellresult error="0" clipped="0" charschecked="5"></spellresult>' 

Tôi đã thông báo rằng khi tôi dán ví dụ của bạn, nó xuất hiện theo thứ tự ngược lại trên thiết bị đầu cuối của tôi từ cách hiển thị trong trình duyệt của tôi. Không quá ngạc nhiên khi xem Hebrew là ngôn ngữ từ phải sang trái.

>>> corpus = u"עברית" 
>>> print corpus[0] 
ע 
+2

Bỏ qua tuyên bố XML là tốt. Bạn chỉ cần nó khi bạn muốn mã hóa không phải UTF hoặc XML 1.1. – bobince

+0

Google thực sự trả về lỗi nếu bạn gửi từ chối XML. – iTayb

+0

@iTayb: Lỗi trông như thế nào? Nó hoạt động tốt trên máy của tôi. – SingleNegationElimination