2012-04-14 11 views
8

私はhttplib.request機能でUnicodeデータを投稿しよう:私は間違っhttplibを使用してユニコード文字を投稿するにはどうすればよいですか?

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) 

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

しかし、これは私のエラーですか?

答えて

9

httpは、特定の文字エンコーディングでは定義されず、代わりにオクテットを使用します。データをエンコーディングに変換する必要があります。次に、使用したエンコーディングをサーバーに伝える必要があります。

このデータは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

XML宣言を送信すると、Googleから実際にエラーが返されます。 – iTayb

+0

@iTayb:エラーはどうなっていますか?私のマシンでうまくいきました。 – SingleNegationElimination

関連する問題