首页 > 解决方案 > 使用 Python 请求立即将 JSON API 响应写入文件

问题描述

我正在尝试从 API 检索数据并立即将 JSON 响应直接写入文件,而不是将响应的任何部分存储在内存中。此要求的原因是因为我在只有 2GB 内存的 AWS Linux EC2 上执行此脚本,如果我尝试将所有内容保存在内存中,然后将响应写入文件,该过程将失败,因为没有足够的内存。

我试过使用f.write()as well as sys.stdout.write(),但这两种方法似乎只在执行所有查询后才写入文件。虽然这适用于我的小例子,但在处理我的实际数据时它不起作用。

以下两种方法的问题是文件在循环完成之前不会填充。这不适用于我的实际过程,因为机器没有足够的内存来保存内存中的所有响应。

我怎样才能适应下面的任何一种方法,或者想出一些新的东西,将从 API 接收到的数据立即写入文件而不在内存中保存任何内容?

注意:我使用的是 Python 3.7,但如果有什么能让这更容易的话,我很乐意更新。

我的方法 1

# script1.py
import requests
import json

with open('data.json', 'w') as f:
    for i in range(0, 100):
        r = requests.get("https://httpbin.org/uuid")
        data = r.json()
        f.write(json.dumps(data) + "\n")
f.close()

我的方法 2

# script2.py
import request
import json
import sys

for i in range(0, 100):
    r = requests.get("https://httpbin.org/uuid")
    data = r.json()
    sys.stdout.write(json.dumps(data))
    sys.stdout.write("\n")

使用方法 2,我尝试使用>将输出重定向到文件:

script2.py > data.json

标签: pythonjsonpython-requestsstdout

解决方案


您可以使用response.iter_content分块下载内容。例如:

import requests


url = 'https://httpbin.org/uuid'

with requests.get(url, stream=True) as r:
    r.raise_for_status()
    with open('data.json', 'wb') as f_out:
        for chunk in r.iter_content(chunk_size=8192): 
            f_out.write(chunk)

保存data.json内容:

{
  "uuid": "991a5843-35ca-47b3-81d3-258a6d4ce582"
}

推荐阅读