簡體   English   中英

如何在大管理器中同時運行異步啟動器/同時運行異步功能

[英]How to concurrently run asynchronous launchers/concurrently run asyncio functions in a big manager

我試圖讓我的代碼運行得更快以查找 roblox 帳戶名稱。 我嘗試使用越來越大的事件循環(他們基本上采用了以前的事件管理器並用它來制作更大的事件管理器),但是與僅使用單個小事件循環相比,這導致了相同的性能,如果不是更差的話。

這段代碼是在我的另一個問題中提供的(這里有我的修改)。 它工作得很好,但處理大量帳戶仍然需要幾分鍾的時間。 通常我不會在意,但我想達到 100,000 個帳戶,所以我需要性能。 這就是它的速度嗎? 或者我們可以進一步推動這一點嗎? 答案只是更多的 CPU/內存嗎? 更好的互聯網? 我是否需要網絡編程,或者有沒有更快的無請求方式?

代碼:

import asyncio
import aiohttp


async def find_account(url, session, id):
    try:
        async with session.get(url) as response:
            if response.status == 200:
                r = await response.read()
                from bs4 import BeautifulSoup
                soup = BeautifulSoup(r, 'html.parser')
                h2 = []
                for i in soup.find_all('h2'):
                    h2.append(i)
                print('Done')
                return str(list(list(h2)[0])[0]) + '  ' + str(url)
            else:
                return 'This account does not exist ID: {}'.format(id)
    except aiohttp.ServerDisconnectedError:
        print('Done')
        return find_account(url, session, id)


async def main(min_id, max_id):
    tasks = []
    async with aiohttp.ClientSession() as session:
        for id in range(min_id, max_id):
            url = f'https://web.roblox.com/users/{str(id)}/profile'
            tasks.append(asyncio.create_task(find_account(url=url, session=session, id=id)))

        return await asyncio.gather(*tasks)


from time import time
loop = asyncio.get_event_loop()
starting = int(input("Type Your Starting Id Number>> "))
ending = int(input("Type Your Ending Id Number>> "))
timer = time()
users = loop.run_until_complete(main(starting, ending))
users = [i for i in users if i != '1']
print(users)
print(time()-timer)

您可以在多個進程中運行BeautifulSoup以加快速度。 例如,您可以提取執行解析的find_account部分find_account其傳遞給進程池執行程序:

import concurrent.futures
_pool = concurrent.futures.ProcessPoolExecutor()

def parse(html):
    from bs4 import BeautifulSoup
    soup = BeautifulSoup(html, 'html.parser')
    h2 = []
    for i in soup.find_all('h2'):
        h2.append(i)
    return str(list(list(h2)[0])[0])

async def find_account(url, session, id):
    while True:
        async with session.get(url) as response:
            if response.status == 200:
                r = await response.read()
                loop = asyncio.get_event_loop()
                extracted = await loop.run_in_executor(_pool, parse, r)
                print('Done')
                return extracted + '  ' + str(url)
            else:
                return 'This account does not exist ID: {}'.format(id)
    except aiohttp.ServerDisconnectedError:
        print('Done')
        # keep looping

在一個不相關的注釋中,您對find_account()遞歸調用不正確,因為它缺少await 上面的代碼修復了這個問題並切換到循環,這使得代碼實際上是循環的更加明確。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM