Asyncio запустить задачу, которая возвращает результат - PullRequest
0 голосов
/ 05 сентября 2018

Я пришел из C # фона, и библиотека Python Asyncio сбивает меня с толку.

Я прочитал следующее 1 2 , однако использование asyncio остается для меня неясным.

Я пытаюсь сделать скребок для сайта на python, который будет асинхронным.

async def requestPage(url):
    request = requests.get(url, headers=headers)
    soup = BeautifulSoup(request.content, 'html.parser')
    return soup


async def main():

    #****** How do I run an async task and store its result to use in another task?
    index_soup = asyncio.ensure_future(requestPage(index_url))
    res = asyncio.gather(index_soup)
    currency_urls = res.select('a[href^="/currencies"]')

    print(currency_urls)


loop = asyncio.get_event_loop()

try:

    loop.run_until_complete(main())
finally:
    loop.close() 

Ответы [ 2 ]

0 голосов
/ 27 сентября 2018

Поскольку библиотека запросов не является асинхронной, вы можете использовать метод run_in_executor , чтобы он не блокировал работающий поток. В результате вы можете определить requestPage как обычную функцию и вызвать ее в функции main следующим образом:

res = await asyncio.gather(loop.run_in_executor(None, requestPage, url)

Функция блокировки будет выполняться в отдельном исполнителе, а элемент управления будет возвращен в цикл обработки событий.

Или вы можете попробовать использовать асинхронную HTTP-клиентскую библиотеку, например aiohttp .

0 голосов
/ 05 сентября 2018

Хорошо, я думаю, что нашел основное решение.

async def requestPage(url):
    request = requests.get(url, headers=headers)
    soup = BeautifulSoup(request.content, 'html.parser')
    return soup


async def getValueAsync(func, param):
    # Create new task
    task = asyncio.ensure_future(func(param))
    # Execute task. This returns a list of tasks
    await asyncio.gather(task)
    # Get result from task
    return task.result()

async def main():
    soup = await getValueAsync(requestPage, index_url)
    print(val.encode("utf-8"))


loop = asyncio.get_event_loop()

try:

    loop.run_until_complete(main())
finally:
    loop.close() 

Я написал оболочку, которая позволяет мне вызывать функцию асинхронно и сохранять результат.

...