【问题标题】:Streaming to a variable instead of a file when using the requests library in Python在 Python 中使用 requests 库时流式传输到变量而不是文件
【发布时间】:2020-04-22 17:33:40
【问题描述】:

我正在使用 Python 的 requests 包从远程服务器下载数据。以前我只是像这样一次性下载整个响应:

response = requests.get(url=endpoint,
                        headers={'Authorization': 'Bearer ' + access_token,
                                 'Content-type': 'application/json'}
                        )

然后使用 response.json() 方法访问数据:

reports = response.json()['data']['report']

但是,由于某些请求会发回相当多的数据,需要几分钟才能下载,因此我被要求为每个请求实现一个进度条,以便用户可以监控正在发生的事情。这里的关键似乎是在发送 GET 请求时使用 stream=True 选项:

response = requests.get(url=endpoint,
                        headers={'Authorization': 'Bearer ' + access_token,
                                 'Content-type': 'application/json'},
                        stream=True)

然后像这样以块的形式下载数据:

with open('output_file', 'wb') as f:
    for chunk in response.iter_content(chunk_size=4096):
        f.write(chunk)
        # print download progress based on chunk size and response.headers.get('content-length')

我卡住的一点是,我使用 response.iter_content() 找到的所有示例在下载时都将每个块直接写入文件(如上例所示)。真的我需要将 JSON 数据下载到本地变量,以便我可以在 写入磁盘之前对其进行一些操作/过滤,但我不确定在以块的形式下载响应时如何实现这一点.

谁能建议如何做到这一点?谢谢。

【问题讨论】:

  • 您是否尝试过:1)首先将文件下载到本地文件系统 2)读取文件并进行必要的操作 3)再次将文件保存到磁盘?我知道这有点笨拙的解决方案,但应该可以工作
  • 这基本上是我的备份计划......但我只是在寻找一个不涉及临时文件的更优雅的解决方案。
  • 你可以使用docs.python.org/3/library/…,这样至少可以节省磁盘I/O。
  • @Ben 我明白了。以防万一——如果目标操作系统是 Linux,文件可能只是 RAM 中的一些东西,不一定是 HDD 或 SSD,所以它可能足够高效

标签: python python-requests


【解决方案1】:

response.iter_content 给你块。你可以对他们做任何你想做的事。您不必将它们写入文件。

例如,您可以将它们放在一个列表中,然后将它们放在一起并在最后解析结果:

import json

chunks = []
for chunk in response.iter_content(chunk_size=4096):
    chunks.append(chunk)
    do_progress_bar_stuff()

full_content = b''.join(chunks)
parsed_data = json.loads(full_content)
do_stuff_with(parsed_data)

(我避免将块与+ 连接,因为这会导致二次运行时间。)

【讨论】:

  • 效果很好,谢谢。现在看起来很明显......我用报告 = json.loads(full_content)['data']['report'] 修改了你的行 parsed_data = json.loads(full_content) 我得到了我的数据结构用的是老办法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-18
  • 1970-01-01
  • 2015-03-13
  • 2013-10-31
  • 2021-07-03
  • 2017-07-23
相关资源
最近更新 更多