In precedenza questione, uno degli autori di aiohttp
modo gentilmente suggerito di fetch multiple urls with aiohttp utilizzando la nuova async with
sintassi da Python 3.5
:asyncio web scraping 101: recupero più URL con 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
Tuttavia quando uno dei session.get(url)
richieste rompe (come sopra a causa di http://SDFKHSKHGKLHSKLJHGSDFKSJH.com
) l'errore non viene gestito e l'intera cosa si interrompe.
ho cercato modi per inserire le prove circa il risultato di session.get(url)
, per esempio, alla ricerca di luoghi per un try ... except ...
, o per una if response.status != 200:
, ma io non sono solo capire come lavorare con async with
, await
ei vari oggetti.
Dal async with
è ancora molto nuovo non ci sono molti esempi. Sarebbe molto utile per molte persone se una procedura guidata asyncio
mostrasse come eseguire questa operazione. Dopo tutto una delle prime cose che la maggior parte delle persone vorranno testare con asyncio
sta ottenendo più risorse contemporaneamente.
Goal
L'obiettivo è che siamo in grado di ispezionare the_results
e vedere rapidamente uno:
- questo URL fallito (e perché: il codice di stato, forse il nome eccezione), o
- questo url ha funzionato, ed ecco un utile oggetto di risposta
Fantastico, grazie mille! Dovrò digerirlo, ma dopo averlo giocato un po 'sembra essere abbastanza flessibile. +1, accetta. :) –
Ottima risposta. Una cosa di cui sono curioso, dato che immediatamente esegui un'iterazione sui risultati dopo aver eseguito 'asyncio.gather', non sarebbe meglio fare' asyncio.as_completed' sulla lista di 'fetch'es? In questo modo puoi scorrere immediatamente quelli completati contro l'attesa che tutti finiscano? – dalanmiller
@dalanmiller: richiede la gestione delle eccezioni, come nella risposta di Padraic Cunningham. Ma se hai bisogno di risultati per ciascun Futuro immediatamente, allora questo è il modo. – kwarunek