2012-04-14 13 views
8

cerco di inviare i dati unicode con la funzione httplib.request:Come posso inserire caratteri unicode usando 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() 

Tuttavia questo è il mio errore:

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) 

Dove sbaglio?

risposta

9

http non è definito in termini di una particolare codifica di caratteri e utilizza invece gli ottetti. Devi convertire i tuoi dati in una codifica, quindi devi dire al server quale codifica hai usato. Consente di utilizzare utf8, poiché di solito è la scelta migliore:

Questi dati assomigliano un po 'a XML, ma si salta il tag xml. Alcuni servizi potrebbero accettarlo, ma non dovresti comunque. In effetti, la codifica in realtà appartiene a questo; quindi assicurati di includerlo. L'intestazione appare come <?xml version="1.0" encoding="codifica"?>.

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

Come una questione di cortesia, si dovrebbe anche dire al server stesso il formato e la codifica, con l'intestazione 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: Si sta lavorando bene sulla mia macchina, sei sicuro di Non stai saltando qualcosa? piena esempio

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

ho notato che quando ho incollato il vostro esempio, appare in ordine inverso sul mio terminale da come si vede nel mio browser. Non troppo sorprendente considerando che l'ebraico è una lingua da destra a sinistra.

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

Omettere la dichiarazione XML va bene. Ne hai bisogno solo quando vuoi una codifica non UTF o XML 1.1. – bobince

+0

Google restituisce effettivamente un errore se si invia la dichiarazione XML. – iTayb

+0

@iTayb: come si presenta l'errore? Ha funzionato bene sulla mia macchina. – SingleNegationElimination

Problemi correlati