所以我根据answers to another question的建议修改了urllib2:
class HttpRequest(urllib2.Request):
def __init__(self, *args, **kwargs):
self._method = kwargs.pop('method', 'GET')
urllib2.Request.__init__(self, *args, **kwargs)
def get_method(self):
return self._method
它适用于带有JSON的PUT:
req = HttpRequest(url=url, method='PUT',
data=json.dumps(metadata))
response = urllib2.urlopen(req)
但它失败了data=
二进制数据(下面的部分堆栈跟踪):
File "c:\appl\python\2.7.2\lib\urllib2.py", line 126, in urlopen
return _opener.open(url, data, timeout)
File "c:\appl\python\2.7.2\lib\urllib2.py", line 394, in open
response = self._open(req, data)
File "c:\appl\python\2.7.2\lib\urllib2.py", line 412, in _open
'_open', req)
File "c:\appl\python\2.7.2\lib\urllib2.py", line 372, in _call_chain
result = func(*args)
File "c:\appl\python\2.7.2\lib\urllib2.py", line 1199, in http_open
return self.do_open(httplib.HTTPConnection, req)
File "c:\appl\python\2.7.2\lib\urllib2.py", line 1168, in do_open
h.request(req.get_method(), req.get_selector(), req.data, headers)
File "c:\appl\python\2.7.2\lib\httplib.py", line 955, in request
self._send_request(method, url, body, headers)
File "c:\appl\python\2.7.2\lib\httplib.py", line 989, in _send_request
self.endheaders(body)
File "c:\appl\python\2.7.2\lib\httplib.py", line 951, in endheaders
self._send_output(message_body)
File "c:\appl\python\2.7.2\lib\httplib.py", line 809, in _send_output
msg += message_body
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 10: ordinal
not in range(128)
我有办法解决这个问题吗?
答案 0 :(得分:1)
这是因为
数据应该是标准application / x-www-form-urlencoded格式的缓冲区。 urllib.urlencode()函数采用2元组的映射或序列,并以此格式返回一个字符串。
答案 1 :(得分:1)
您正在尝试自动将python unicode字符串转换为常规字节字符串。 JSoN始终是unicode,但HTTP必须发送字节。如果您确信接收方能够理解特定编码中的json编码数据,您可以按照这种方式对其进行编码:
>>> urllib2.urlopen(urllib2.Request("http://example.com", data=u'\u0ca0'))
Traceback (most recent call last):
...
UnicodeEncodeError: 'ascii' codec cannot encode character u'\u0ca0' in position 0: ordinal not in range(128)
>>> urllib2.urlopen(urllib2.Request("http://example.com",
... data=u'\u0ca0'.encode('utf-8')))
<addinfourl at 15700984 whose fp = <socket._fileobject object at 0xdfbe50>>
>>>
请注意.encode('utf-8')
,它会在utf-8中将unicode
转换为str
。隐式转换将使用ascii,它不能编码非ascii字符。
tl; dr ... data=json.dumps(blabla).encode('utf-8') ...
答案 2 :(得分:-1)
根据urllib2 documentation,您需要对字节串进行百分比编码。