2013-05-16 36 views
1

我使用Python的请求包来编写一个简单的REST客户端。 这是我的代码 -蟒蛇请求分块响应

r = requests.get(url, auth=(user, passwd), stream=True, verify=False) 
print('headers: ') 
pprint.pprint(r.headers) 
print('status: ' + str(r.status_code)) 
print('text: ' + r.text) 

这里是输出 -

headers: 
    {'content-type': 'text/xml;charset=UTF-8', 
    'date': 'Thu, 16 May 2013 03:26:06 GMT', 
    'server': 'Apache-Coyote/1.1', 
    'set-cookie': 'JSESSIONID=779FC39...5698; Path=/; Secure; HttpOnly', 
    'transfer-encoding': 'chunked'} 
status: 200 

Traceback (most recent call last): 
    File "C:\...\client.py", line 617, in _readinto_chunked 
    chunk_left = self._read_next_chunk_size() 
    File "C:\...\client.py", line 562, in _read_next_chunk_size 
    return int(line, 16) 
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xce in position 0: invalid continuation byte 

该请求的响应是XML。看起来像是分块。 是否有特殊的方式来读取分块响应?我想将整个XML响应放在一个字符串中。

回答

1

你只用不完stream=True,当你在遍历响应的内容策划。如果您打算立即打印响应内容,则stream=True不会为您带来任何性能优势。它只会将内容加载到内存中,直到您拨打r.textr.content,然后将其加载到内存中。如果您想防止将整个内容加载到内存中,请查看下面的内容。对于其他问题,试试这个:

print('text:') 
print(r.text) 

print('text: ' + r.content) 

如果你在2.x中,r.text是一个Unicode对象可能不能够被转化为ASCII。

我不明白为什么分块的响应不会没有stream=True工作,但只有这样,才能正确地使用它(无需下载所有的这一次像你r.contentr.text做)是为使用iter_contentiter_lines。收集所有的响应内容为一个字符串,可以做到以下几点:

contents = ''.join(r.iter_content(224)) # stole the number from your comment 

相关提示:在使用上返回的字符串decode方法提供高度不一致的结果。如果您的API允许它发送Accept-Encoding标题,那么您始终可以确保获取可以解码的数据。

你不是已经这样做了,所以我不建议,但如果你在打印的信息坚持,那么你会需要它,尤其是如果它是一个国际上流行的API网站。

+0

抱歉,但你对流说法是不正确的。 请求文档 - “默认情况下,当你犯了一个请求,响应的主体被立即下载您可以覆盖此行为,并推迟下载响应身体,直到你进入Response.content与流参数的属性。”续 –

+0

- 对于分块响应,不使用“stream = true”会导致真正奇怪的错误,就像我上面显示的那样。我刚才试了一下,我得到这个错误 - “的UnicodeDecodeError:‘UTF-8’编解码器不能在位置2解码字节0x96:无效的起始字节” 我想你提到的其他选择,我也得到相同的错误。 howvever,this works - rString = r.raw.read(224).decode() 这里,224代表响应字节长度。 –

+0

@QuestMonger我知道'stream = True'不会导致'UnicodeDecodeError'。这是服务器和你之间的编码问题(即试图打印数据)。无论如何,我用一种将所有响应收集到一个字符串中的方式更新了我的答案。 –