【问题标题】:How to run while True in asyncio python?如何在 asyncio python 中运行时为真?
【发布时间】:2017-06-26 21:56:13
【问题描述】:

我正在使用asyncio/aiohttp 向不同的网站发送异步GET 请求。计划是从redis 队列中获取100 个url,并异步向它们发送GET 请求。然后再获取 100 个 url 并重复该过程。此外,如果 url 失败(超时或 HTTP_status == 403),该进程会将其添加到队列的末尾。我已经编写了一个代码来实现这一点,但它会在一段时间后冻结。谁能告诉我如何实现它?这是我的代码:

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)

【问题讨论】:

  • 你的函数等待 3 个参数 def run(url_list,headers,r_server): 但你只给它 2 个 asyncio.ensure_future(run(url_list,r_server))
  • 感谢指正。编辑了问题。
  • 抱歉,在您找到脚本冻结点之前,无法为您提供帮助。但是使用同步 redis 客户端并一遍又一遍地运行事件循环是反模式。

标签: python asynchronous async-await python-asyncio aiohttp


【解决方案1】:

质疑: 如何在 asyncio python 中运行时为真?

替换

loop.run_until_complete(future)

loop.run_forever(future)

【讨论】:

  • 你不能run_forever()一个未来。 run_forever() 不接受参数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-14
  • 1970-01-01
  • 2019-07-28
  • 1970-01-01
相关资源
最近更新 更多