В предыдущий вопрос, один из авторов aiohttp
любезно предложил способ fetch multiple urls with aiohttp используя новый async with
синтаксис из Python 3.5
:asyncio веб выскабливание 101: извлечение нескольких веб-адресов с aiohttp
import aiohttp
import asyncio
async def fetch(session, url):
with aiohttp.Timeout(10):
async with session.get(url) as response:
return await response.text()
async def fetch_all(session, urls, loop):
results = await asyncio.wait([loop.create_task(fetch(session, url))
for url in urls])
return results
if __name__ == '__main__':
loop = asyncio.get_event_loop()
# breaks because of the first url
urls = ['http://SDFKHSKHGKLHSKLJHGSDFKSJH.com',
'http://google.com',
'http://twitter.com']
with aiohttp.ClientSession(loop=loop) as session:
the_results = loop.run_until_complete(
fetch_all(session, urls, loop))
# do something with the the_results
Однако, когда один из session.get(url)
запросов брейков (как указано выше из-за http://SDFKHSKHGKLHSKLJHGSDFKSJH.com
) ошибка не обрабатывается, и вся вещь ломается.
Я искал способы вставки тестов о результате session.get(url)
, например, ищу места для try ... except ...
, или для if response.status != 200:
, но я просто не понять, как работать с async with
, await
и различными объектами.
С async with
по-прежнему очень много новых примеров. Было бы очень полезно многим людям, если бы мастер asyncio
мог показать, как это сделать. В конце концов, одна из первых вещей, которые большинство людей захотят протестировать, с asyncio
получает несколько ресурсов одновременно.
Гол
Цель состоит в том, что мы можем осмотреть the_results
и быстро увидеть, как:
- этот URL не удалось (и почему: код статуса, может быть, имя исключения), или
- это url работал, и вот полезный объект ответа
Потрясающе, большое вам спасибо! Мне нужно переварить это, но, немного поиграв с ним, кажется, что он довольно гибкий. +1, принять. :) –
Отличный ответ. Одна вещь, о которой мне интересно, поскольку вы сразу же перебираете результаты после выполнения 'asyncio.gather', было бы лучше сделать' asyncio.as_completed' в списке 'fetch'es? Таким образом, вы можете перебирать завершенные сразу и ждать их завершения? – dalanmiller
@ dalanmiller: для этого требуется обработка исключений, как в ответе Padraic Cunningham. Но если вам нужен результат для каждого Будущего сразу, то это именно так. – kwarunek