Asynchronous 使用Asyncio+;在下一个请求中用作参数的一个请求的输出;Aiohttp

Asynchronous 使用Asyncio+;在下一个请求中用作参数的一个请求的输出;Aiohttp,asynchronous,async-await,python-asyncio,aiohttp,Asynchronous,Async Await,Python Asyncio,Aiohttp,我不熟悉异步编程、异步IO、Aiohttp世界 我有多个请求,其中第一个请求的-输出被用作第二个请求中的参数 到目前为止,我已经尝试了这么多- import aiohttp import asyncio async def get_response(session, url, params): async with session.get(url=url, params=params) as response: response = await response.js

我不熟悉异步编程、异步IO、Aiohttp世界

我有多个请求,其中第一个请求的-输出被用作第二个请求中的参数

到目前为止,我已经尝试了这么多-

import aiohttp
import asyncio


async def get_response(session, url, params):
    async with session.get(url=url, params=params) as response:
        response = await response.json()
        return response['output']


async def main():

    tasks = []

    url = "https://example.api.com/"

    url_1 = url + 'path_1'
    url_2 = url + 'path_2'

    params = {'name': "Hello"}

    async with aiohttp.ClientSession() as session:

        a1 = get_response(session, url_1, params)
        tasks.append(a1)

        params = {'name': a1}
        b1 = get_response(session, url_2, params)
        tasks.append(b1)

        responses = await asyncio.gather(*tasks, return_exceptions=True)

        print(responses)

loop = asyncio.get_event_loop()
loop.run_until_complete(main())
我得到了一个明显的错误-

TypeError("Invalid variable type: value should be str, int or float, got <coroutine object get_response at 0x00000000037FA6C0> of type <class 'coroutine'>")

如果第二个协同路由需要第一个协同路由的结果,那么您不能同时运行两个协同路由,您需要等待第一个协同路由的响应。例如:

async def get_both(session, url_1, url_2, params_1):
    a1 = await get_response(session, url_1, params_1)
    params_2 = {'name': a1}
    b1 = await get_response(session, url_2, params_2)
    return a1, b1  # or just b1 if you don't need a1
您的
main()
将如下所示:

async def main():
    url = "https://example.api.com/"
    url_1 = url + 'path_1'
    url_2 = url + 'path_2'
    params = {'name': "Hello"}

    async with aiohttp.ClientSession() as session:
        responses = await get_both(session, url_1, url_2, params)
        print(responses)
当然,您不会得到并行抓取,但这是一个请求依赖于另一个请求的结果这一事实的直接结果。您可以轻松地并行化
get\u both
的多个实例-例如,如果
url\u 1
url\u 2
是列表,您可以执行以下操作:

async def main():
    url_list_1 = [...]
    url_list_2 = [...]
    params = {'name': "Hello"}

    async with aiohttp.ClientSession() as session:
        coros = [get_both(session, url_1, url_2, params)
                 for url_1, url_2 in zip(url_list_1, url_list_2)]
        all_responses = await asyncio.gather(*coros)
        print(all_responses)

如果第二个协同路由需要第一个协同路由的结果,那么您不能同时运行两个协同路由,您需要等待第一个协同路由的响应。例如:

async def get_both(session, url_1, url_2, params_1):
    a1 = await get_response(session, url_1, params_1)
    params_2 = {'name': a1}
    b1 = await get_response(session, url_2, params_2)
    return a1, b1  # or just b1 if you don't need a1
您的
main()
将如下所示:

async def main():
    url = "https://example.api.com/"
    url_1 = url + 'path_1'
    url_2 = url + 'path_2'
    params = {'name': "Hello"}

    async with aiohttp.ClientSession() as session:
        responses = await get_both(session, url_1, url_2, params)
        print(responses)
当然,您不会得到并行抓取,但这是一个请求依赖于另一个请求的结果这一事实的直接结果。您可以轻松地并行化
get\u both
的多个实例-例如,如果
url\u 1
url\u 2
是列表,您可以执行以下操作:

async def main():
    url_list_1 = [...]
    url_list_2 = [...]
    params = {'name': "Hello"}

    async with aiohttp.ClientSession() as session:
        coros = [get_both(session, url_1, url_2, params)
                 for url_1, url_2 in zip(url_list_1, url_list_2)]
        all_responses = await asyncio.gather(*coros)
        print(all_responses)

嗨,我很好奇我的回答是否有助于你的问题?嗨,我很好奇我的回答是否有助于你的问题?