как менять прокси на каждом запросе используя aiohttp

когда мне нужно асинхронно отправить несколько get запросов я делаю так:

async def fetch(session, url):
    headers={
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36'
    }
    async with session.get(url, ssl=ssl.SSLContext(), headers=headers) as resp:
        return await resp.text()

async def main():
    items_list=[
        'https://www.ebay-kleinanzeigen.de/s-bestandsliste.html?userId=8354390', 
        'https://www.ebay-kleinanzeigen.de/s-bestandsliste.html?userId=7672003', 
        'https://www.ebay-kleinanzeigen.de/s-bestandsliste.html?userId=7672003', 
        'https://www.ebay-kleinanzeigen.de/s-bestandsliste.html?userId=7672003'
    ]

    proxys=[
        'http://xxxxxxxxxxxxxxxxx', 
        'http://xxxxxxxxxxxxxxxxxx', 
        'http://xxxxxxxxxxxxxxxxxxxx', 
        'http://xxxxxxxxxxxxxxxxxxxxxxxx'
    ]
    proxy=random.choice(proxys)
    connector = ProxyConnector.from_url(proxy)
    loop = asyncio.get_event_loop()
    async with aiohttp.ClientSession(loop=loop, connector=connector) as session:
        html_links = await asyncio.gather(*[fetch(session, url) for url in items_list])


if __name__=='__main__':
    asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
    asyncio.run(main())

при этом прокси я прописываю в сессию 1 раз и один прокси будет общим для всех get запросов внутри функции fech. как мне сделать так чтобы запросы отправлялись так же асинхронно, но на каждом запросе менялись прокси?


Ответы (1 шт):

Автор решения: tesseractmaks
 items_list=[
                'http://icanhazip.com',
                'http://icanhazip.com',
                'http://icanhazip.com',
                'http://icanhazip.com',
            ]

  # прокси замените, могут не работать
  proxys=[
    'http://107.151.182.247:80',
    'http://107.151.182.247:80',
    'http://107.151.182.247:80',
    'http://107.151.182.247:80',
    'http://107.151.182.247:80',
    'http://107.151.182.247:80',
    'http://107.151.182.247:80',
    'http://107.151.182.247:80',
]


async def fetch(session, url):
    async with session.get(url[0], timeout=3, proxy=url[1]) as resp:
        if resp.ok:
            result = await resp.read()
            print(result)
    


async def func():
     proxies = random.sample(proxys, k=len(proxys))
        
     async with aiohttp.ClientSession() as session:
         html_links = [fetch(session, url) for url in zip(items_list, proxies)]
         return await asyncio.gather(*html_links)
        
        
        
def main():
    asyncio.run(func())
        
        
if __name__ == "__main__":
    main()

headers - динамические, поэтому прописывать не нужно. Генерятся в ClientSession()

ssl.SSLContext() - не нужен(он для пользовательской проверки SSL-сертификата), его заменяет параметр verify_ssl. По умолчанию включено. Можно отключить, чтобы пропустить проверку для сайтов с недействительными сертификатами так:

 async def fetch(session, url):
    async with session.get(url[0], proxy=url[1], ssl=False) as resp:
      .....
→ Ссылка