我有一个多个REST API端点(URL)来传输数据.我想知道在一个/多个过程中读取所有这些内容的最佳方法是什么.

目前我只从一个URL读取数据,执行如下操作:

    s = requests.Session()
    resp = s.get(url, headers=headers, stream=True)
    for line in resp.iter_lines():
        if line:
            print(line)

我想用更多的URL做同样的事情,我想知道这里最好的方法是什么.

推荐答案

下面是一个使用concurrent.futures.ThreadPoolExecutor读取多个URL的示例.但这只是一种方法,你可以使用multiprocessingasyncio/aiohttp等.

from concurrent.futures import ThreadPoolExecutor

import requests


def get_from_api(tpl):
    session, url = tpl

    resp = session.get(url, stream=True)

    # just for example:
    count_lines = 0
    for line in resp.iter_lines():
        count_lines += 1

    return url, count_lines


def main():
    api_urls = [
        "https://google.com",
        "https://yahoo.com",
        "https://facebook.com",
        "https://instagram.com",
        # ...etc.
    ]

    with ThreadPoolExecutor(max_workers=2) as pool, requests.session() as session:
        for url, count_lines in pool.map(
            get_from_api, ((session, url) for url in api_urls)
        ):
            print(url, count_lines)


if __name__ == "__main__":
    main()

打印:

https://google.com 17
https://yahoo.com 648
https://facebook.com 26
https://instagram.com 50

编辑:使用asyncio/aiohttp:

import asyncio

# Streaming API:
# https://docs.aiohttp.org/en/stable/streams.html#streaming-api
import aiohttp


async def fetch(session, url):
    while True:
        async with session.get(url) as response:
            reader = response.content

            cnt = 0
            async for line in reader:
                cnt += 1

            print(f"{url}: {cnt} lines read")

        await asyncio.sleep(3)


async def main():
    urls = [
        "https://google.com",  # Replace with actual URLs
        "https://facebook.com",
    ]

    async with aiohttp.ClientSession() as session:
        tasks = {asyncio.create_task(fetch(session, url)) for url in urls}

        # this loops indifinitely:
        await asyncio.gather(*tasks)


if __name__ == "__main__":
    asyncio.run(main())

打印:

https://google.com: 17 lines read
https://facebook.com: 26 lines read
https://google.com: 655 lines read
https://facebook.com: 26 lines read

...

Python相关问答推荐

为什么判断pd.DataFrame的值与判断pd.Series的值存在差异(如果索引中有值)?

Django:如何将一个模型的唯一实例创建为另一个模型中的字段

仅对matplotlib的条标签中的一个条标签应用不同的格式

KNN分类器中的GridSearchCV

Pydantic:如何将对象列表表示为dict(将列表序列化为dict)

有什么方法可以避免使用许多if陈述

如何根据情况丢弃大Pandas 的前n行,使大Pandas 的其余部分完好无损

计算相同形状的两个张量的SSE损失

GL pygame无法让缓冲区与vertextPointer和colorPointer一起可靠地工作

如何在Deliveryter笔记本中从同步上下文正确地安排和等待Delivercio代码中的结果?

类型错误:输入类型不支持ufuncisnan-在执行Mann-Whitney U测试时[SOLVED]

对于一个给定的数字,找出一个整数的最小和最大可能的和

如何在polars(pythonapi)中解构嵌套 struct ?

Python解析整数格式说明符的规则?

组/群集按字符串中的子字符串或子字符串中的字符串轮询数据框

如何根据一列的值有条件地 Select 前N个组,然后按两列分组?

多处理队列在与Forking http.server一起使用时随机跳过项目

如何指定列数据类型

如何从需要点击/切换的网页中提取表格?

在单次扫描中创建列表