【问题标题】:python requests chunked responsepython请求分块响应
【发布时间】:2013-05-16 03:43:20
【问题描述】:

我正在使用 Python Requests 包编写一个简单的 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 响应放在一个字符串中。

【问题讨论】:

    标签: xml python-requests chunked-encoding


    【解决方案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 .

    【讨论】:

    • 抱歉,您关于流的说法不正确。请求文档 - “默认情况下,当您发出请求时,会立即下载响应正文。您可以覆盖此行为并推迟下载响应正文,直到您使用流参数访问 Response.content 属性”
    • 续 - 不使用 'stream=true' 进行分块响应会导致非常奇怪的错误,就像我上面显示的那样。我刚试过,我得到了这个错误 - “UnicodeDecodeError:'utf-8'编解码器无法解码位置2的字节0x96:无效的起始字节”我尝试了你提到的其他选项,我得到了同样的错误。但是,这可行 - rString = r.raw.read(224).decode() 在这里,224 表示响应字节长度。
    • @QuestMonger 我知道stream=True 不会导致UnicodeDecodeError。这是服务器和您之间的编码问题(即尝试打印数据)。无论如何,我用一种将所有响应收集到一个字符串中的方法更新了我的答案。
    • UnicodeDecodeError 问题出在 restful api 上。它有一些编码/响应问题。我将接受上述答案,因为它最接近我们得到的解决方案。
    猜你喜欢
    • 2011-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-04
    • 2017-09-22
    • 2021-10-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多