J'utilise asyncio/aiohttp
pour envoyer une requête asynchrone GET
à différents sites Web. Le plan consiste à extraire 100 urls d'une file d'attente redis et à leur envoyer une requête GET
de manière asynchrone. Ensuite, récupérez 100 autres URL et répétez le processus. En outre, si une URL échoue (timeout ou HTTP_status == 403), le processus l'ajoutera à la fin de la file d'attente. J'ai écrit un code pour y parvenir, mais il se bloque après un certain temps. Quelqu'un peut-il me dire comment y parvenir? Voici mon code:Comment s'exécuter en True dans asyncio python?
import asyncio
from aiohttp import ClientSession
import async_timeout
import aiohttp
import aiosocks
import redis
import json
url_list = []
async def fetch(url, session,r_server):
agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'
headers = {'user-Agent': agent,'accept-Language':'en-US,en;q=0.8','accept':'text/javascript, application/javascript,
application/ecmascript, application/x-ecmascript, */*; q=0.01',
'accept-Encoding':'gzip, deflate, sdch, br','x-requested-with':'XMLHttpRequest'}
with async_timeout.timeout(100):
async with session.get(url,headers=headers) as response:
status = response.status
# Store status code somewhere
...
async def bound_fetch(sem, url, session,r_server):
# Getter function with semaphore.
async with sem:
try:
await fetch(url, session,r_server)
except Exception as e:
print ("In semaphore",e,url)
# Push url in redis queue
...
async def run(url_list,r_server):
tasks = []
# create instance of Semaphore
sem = asyncio.Semaphore(1000)
# Create client session that will ensure we dont open new connection
# per request.
async with ClientSession() as session:
for url in url_list:
# pass Semaphore and session to every GET request
task = asyncio.ensure_future(bound_fetch(sem, url, session,r_server))
tasks.append(task)
responses = asyncio.gather(*tasks)
await responses
async def get_url_list(r_server):
url_list = []
# Get url list from redis: queue_list
for docs in queue_list:
doc = json.loads(docs.decode("utf-8"))
url = doc["url"]
url_list.append(url)
loop = asyncio.get_event_loop()
future = asyncio.ensure_future(run(url_list,r_server))
loop.run_until_complete(future)
if __name__ == "__main__":
r_server = redis.Redis("localhost")
while True:
get_url_list(r_server)
time.sleep(5)
Vous fonctionnez attend 3 argumetns'Exécuter def (url_list, en-têtes, r_server): 'mais vous donnez seulement 2' asyncio.ensure_future (run (url_list, r_server)) ' – vZ10
Merci pour la correction. Edité la question. – Rahul
Désolé, mais il est impossible de vous aider jusqu'à ce que vous ayez trouvé le point où votre script gèle. Mais l'utilisation du client redis synchrone et de la boucle d'événement en cours d'exécution est anti-pattern. –