如何保存异步请求的 JSON 响应?

pol*_*ist 6 python python-asyncio aiohttp

我有一个关于异步请求的问题:

如何response.json()即时保存到文件?

我想发出请求并将响应保存到文件中.json,而不将其保留在内存中。


import asyncio
import aiohttp


async def fetch(sem, session, url):
    async with sem:
        async with session.get(url) as response:
            return await response.json() # here


async def fetch_all(urls, loop):
    sem = asyncio.Semaphore(4) 
    async with aiohttp.ClientSession(loop=loop) as session:
        results = await asyncio.gather(
            *[fetch(sem, session, url) for url in urls]
        )
        return results


if __name__ == '__main__':

    urls = (
        "https://public.api.openprocurement.org/api/2.5/tenders/6a0585fcfb05471796bb2b6a1d379f9b",
        "https://public.api.openprocurement.org/api/2.5/tenders/d1c74ec8bb9143d5b49e7ef32202f51c",
        "https://public.api.openprocurement.org/api/2.5/tenders/a3ec49c5b3e847fca2a1c215a2b69f8d",
        "https://public.api.openprocurement.org/api/2.5/tenders/52d8a15c55dd4f2ca9232f40c89bfa82",
        "https://public.api.openprocurement.org/api/2.5/tenders/b3af1cc6554440acbfe1d29103fe0c6a",
        "https://public.api.openprocurement.org/api/2.5/tenders/1d1c6560baac4a968f2c82c004a35c90",
    ) 

    loop = asyncio.get_event_loop()
    data = loop.run_until_complete(fetch_all(urls, loop))
    print(data)
Run Code Online (Sandbox Code Playgroud)

目前,该脚本仅打印 JSON 文件,一旦它们全部被删除,我就可以保存它们:

data = loop.run_until_complete(fetch_all(urls, loop))
for i, resp in enumerate(data):
    with open(f"{i}.json", "w") as f:
        json.dump(resp, f)
Run Code Online (Sandbox Code Playgroud)

但它对我来说感觉不对,因为例如,一旦我耗尽内存,它肯定会失败。

有什么建议么?


编辑

我的帖子仅限于一个问题

use*_*342 3

如何response.json()即时保存到文件?

response.json()首先不要使用,而是使用流 API

async def fetch(sem, session, url):
    async with sem, session.get(url) as response:
        with open("some_file_name.json", "wb") as out:
            async for chunk in response.content.iter_chunked(4096)
                out.write(chunk)
Run Code Online (Sandbox Code Playgroud)

  • @politicalscientist 是的,您使用它的方式既正确又惯用。 (2认同)