2012-04-14 4 views
8

는 내가 httplib.request 기능을 유니 코드 데이터를 게시하려고 : 내가 잘못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는 특정 문자 인코딩과 관련하여 정의되지 않고 대신 옥텟을 사용합니다. 데이터를 인코딩으로 변환해야하며 서버에 사용 된 인코딩을 알려줘야합니다. 일반적으로 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'}) 

편집 : 그것은 내 컴퓨터에서 잘 작동, 당신은 당신이 확신 뭔가를 건너 뛰지 않아? 전체 예제

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

관련 문제