2012-04-14 1 views
8

Я стараюсь размещать данные Юникода с функцией httplib.request:Как отправить символы юникода с помощью 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() 

Однако это моя ошибка:

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) 

Где я ошибаюсь?

ответ

9

http не определен в терминах конкретной кодировки символов и вместо этого использует октеты. Вам нужно преобразовать ваши данные в кодировку, а затем вам нужно указать серверу, какую кодировку вы использовали. Используется utf8, так как обычно это лучший выбор:

Эти данные немного похожи на XML, но вы пропускаете тег xml. Некоторые службы могут принять это, но вы не должны в любом случае. Фактически, кодирование на самом деле там; поэтому убедитесь, что вы включили его. Заголовок выглядит как <?xml version="1.0" encoding="кодировка"?>.

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') 

Как из вежливости, вы должны также сказать, сам формат и кодирование сервера, с заголовком content-type:

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

EDIT: Это работает отлично на моей машине, вы уверены, «Не пропускаешь что-то? Полный пример

>>> 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>' 

Я заметил, что, когда я вставил свой пример, он появляется в обратном порядке на моем терминале от того, как он показывает в своем браузере. Не слишком удивительно, учитывая, что иврит - это язык справа налево.

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

Опуская Декларацию XML в порядке. Вам это нужно только тогда, когда вам нужна кодировка, отличная от UTF, или XML 1.1. – bobince

+0

Google действительно возвращает ошибку, если вы отправляете декларацию XML. – iTayb

+0

@iTayb: Как выглядит ошибка? Он отлично работал на моей машине. – SingleNegationElimination

 Смежные вопросы

  • Нет связанных вопросов^_^