2017-06-26 5 views
0

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) 
+0

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

+0

Merci pour la correction. Edité la question. – Rahul

+0

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. –

Répondre

0

Ouestion: Comment exécuter while True dans asyncio python?

Replace

loop.run_until_complete(future) 

avec

loop.run_forever(future)