Aiohttp запросы асинхронной сессии - PullRequest
1 голос
/ 20 марта 2019

Итак, я просматривал защищенные страницы веб-сайта (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 Ответ

2 голосов
/ 20 марта 2019

Это самое простое, что я могу придумать, в зависимости от того, что вы делаете в <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())
...