Aiohttp запросы асинхронной сессии
Поэтому я просматривал защищенные страницы веб-сайта (www.cardsphere.com) с запросами, используя сеанс, например:
import requests
payload = {
'email': <enter-email-here>,
'password': <enter-site-password-here>
}
with requests.Session() as request:
requests.get(<site-login-page>)
request.post(<site-login-here>, data=payload)
request.get(<site-protected-page1>)
save-stuff-from-page1
request.get(<site-protected-page2>)
save-stuff-from-page2
.
.
.
request.get(<site-protected-pageN>)
save-stuff-from-pageN
the-end
Теперь, так как это довольно много страниц, я хотел ускорить его с помощью Aiohttp + asyncio... но я что-то упустил. Я был в состоянии более или менее использовать его для удаления незащищенных страниц, например так:
import asyncio
import aiohttp
async def get_cards(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as resp:
data = await resp.text()
<do-stuff-with-data>
urls = [
'https://www.<url1>.com'
'https://www.<url2>.com'
.
.
.
'https://www.<urlN>.com'
]
loop = asyncio.get_event_loop()
loop.run_until_complete(
asyncio.gather(
*(get_cards(url) for url in urls)
)
)
Это дало некоторые результаты, но как мне сделать это для страниц, которые требуют входа? Я пытался добавить session.post(<login-url>,data=payload)
внутри асинхронной функции, но это, очевидно, не сработало, она просто продолжит вход в систему. Есть ли способ "установить" aiohttp ClientSession перед функцией цикла? Как мне нужно войти в систему, а затем, в том же сеансе, получить данные из набора защищенных ссылок с помощью asyncio + aiohttp?
Все еще довольно плохо знакомый с python, тем более асинхронный, я пропускаю здесь некоторые ключевые концепции. Если кто-нибудь укажет мне правильное направление, я буду очень признателен.
1 ответ
Это самое простое, что я могу придумать, в зависимости от того, что вы делаете в <do-stuff-with-data>
Вы можете столкнуться с некоторыми другими проблемами, связанными с параллелизмом, по кроличьей норе, в которую вы идете... шутка, немного сложнее обернуть голову вокруг пустот, обещаний и заданий, но как только вы это получите, это так же просто, как последовательное программирование
import asyncio
import aiohttp
async def get_cards(url, session, sem):
async with sem, session.get(url) as resp:
data = await resp.text()
# <do-stuff-with-data>
urls = [
'https://www.<url1>.com',
'https://www.<url2>.com',
'https://www.<urlN>.com'
]
async def main():
sem = asyncio.Semaphore(100)
async with aiohttp.ClientSession() as session:
await session.get('auth_url')
await session.post('auth_url', data={'user': None, 'pass': None})
tasks = [asyncio.create_task(get_cards(url, session, sem)) for url in urls]
results = await asyncio.gather(*tasks)
return results
asyncio.run(main())