使用 aiohttp 的 Python 3.6 异步 GET 请求同步运行

标签 python python-3.x http python-asyncio aiohttp

我的以下功能正常运行,但由于某种原因,请求似乎是同步执行的,而不是异步执行的。

我现在的假设是,这是因为 main 函数中的 for record in records for 循环而发生的,但我不确定如何更改它以便请求可以异步执行。如果不是这种情况,我还需要更改什么?

async def do_request(query_string):
        base_url = 'https://maps.googleapis.com/maps/api/place/textsearch/json?'
        params = {'key': google_api_key,
                  'query': query_string}
        async with aiohttp.ClientSession() as session:
            async with session.request('GET', base_url, params=params) as resp:
                return resp


async def main():
    create_database_and_tables()
    records = prep_sample_data()[:100]

    for record in records:
        r = Record(record)

        if not r.is_valid:
            continue

        query_string = r.generate_query_string()

        resp = await do_request(query_string)
        print("NOW WRITE TO DATABASE")

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())

最佳答案

您正在依次等待单独的 do_request() 调用。不要直接等待它们(在协程完成之前阻塞),而是使用 asyncio.gather() function让事件循环同时运行它们:

async def main():
    create_database_and_tables()
    records = prep_sample_data()[:100]

    requests = []
    for record in records:
        r = Record(record)

        if not r.is_valid:
            continue

        query_string = r.generate_query_string()

        requests.append(do_request(query_string))

    for resp in asyncio.gather(*requests):
        print("NOW WRITE TO DATABASE")

asyncio.gather() 返回值是协程返回的所有结果的列表,其顺序与您将它们传递给 gather() 函数的顺序相同。

如果您需要原始记录来处理响应,您可以通过几种不同的方式将记录和查询字符串配对:

  • 将有效记录存储在单独的列表中,并在处理响应时使用 zip() 将它们再次配对
  • 使用辅助协程获取有效记录、生成查询字符串、调用请求并将记录和响应作为元组一起返回。

您还可以将响应处理混合到一个聚集的协程中;一个获取记录,生成查询字符串,等待 do_request,然后在响应准备好时将结果存储在数据库中。

换句话说,将需要连续发生的工作分配到协程中,然后将它们收集起来。

关于使用 aiohttp 的 Python 3.6 异步 GET 请求同步运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49118449/

相关文章:

java - 在 Java 中使用 Gson 解析来自 HTTP 请求的 JSON 响应

Python 3.6 启动报错

python - 尝试 MNIST 数据集时,tensorflow 和 matplotlib 包出现问题

python - tensorflow 中的等效列表理解

python - 尝试为一个月中的每一天创建文件

python - 在不同的文件中加载 pickle 对象 - 属性错误

java - Jersey 使用 POST 接受文件参数和字符串

python - 为机器学习模型创建标记图像数据集

python - 按模式对列表进行排序

http - 如何在重定向到 SSL 期间保持相同的 ASP session ?