Асинхронные почтовые запросы Python

Мне было интересно, есть ли способ сделать этот скрипт намного быстрее - например, мгновенно создать 1000 учетных записей или, по крайней мере, за несколько секунд. Я сам пробовал делать кое-что с асинхронностью, но это все, что я мог сделать, я только новичок в асинхронном программировании, поэтому любая помощь приветствуется.

import asyncio
import aiohttp


async def make_numbers(numbers, _numbers):
    for i in range(numbers, _numbers):
        yield i

async def make_account():
   url = "https://example.com/sign_up.php"
   async with aiohttp.ClientSession() as session:
          async for x in make_numbers(35691, 5000000):
              async with  session.post(url, data ={
                    "terms": 1,
                    "captcha": 1,
                    "email": "user%[email protected]" % str(x),
                    "full_name": "user%s" % str(x),
                    "password": "123456",
                    "username": "auser%s" % str(x)
              }) as response:
                    data = await response.text()
                    print("-> Creating account number %d" % x)
                    print (data)

loop = asyncio.get_event_loop()
try:
    loop.run_until_complete(make_account())
finally:
    loop.close()

person Kevin    schedule 06.08.2018    source источник


Ответы (2)


Код в вопросе выполняет все запросы POST в серии, делая код не быстрее, чем если бы вы использовали requests в одном потоке. Но в отличие от requests, asyncio позволяет распараллелить их в одном потоке:

async def make_account():
    url = "https://example.com/sign_up.php"
    async with aiohttp.ClientSession() as session:
        post_tasks = []
        # prepare the coroutines that post
        async for x in make_numbers(35691, 5000000):
            post_tasks.append(do_post(session, url, x))
        # now execute them all at once
        await asyncio.gather(*post_tasks)

async def do_post(session, url, x):
    async with session.post(url, data ={
                "terms": 1,
                "captcha": 1,
                "email": "user%[email protected]" % str(x),
                "full_name": "user%s" % str(x),
                "password": "123456",
                "username": "auser%s" % str(x)
          }) as response:
          data = await response.text()
          print("-> Created account number %d" % x)
          print (data)

Приведенный выше код попытается отправить все запросы POST одновременно. Несмотря на намерение, он будет ограничен TCP-коннектором aiohttp.ClientSession, который по умолчанию допускает до 100 одновременных подключений. Чтобы увеличить или снять это ограничение, необходимо установить пользовательский соединитель. в сеансе.

person user4815162342    schedule 06.08.2018

Асинхронный код, который вы разместили, выглядит нормально для меня. Вы можете ускорить его, комбинируя asyncio с многопоточностью/многопроцессорностью.

Но есть и другие ограничения, которые не позволяют создавать 1000 аккаунтов в секунду. Например, скорость сети, одновременные подключения, ограничение скорости, IOPS базы данных на стороне сервера.

person shaun shia    schedule 06.08.2018