IT story

asyncio에서 요청을 어떻게 사용할 수 있습니까?

hot-time 2020. 7. 30. 09:49
반응형

asyncio에서 요청을 어떻게 사용할 수 있습니까?


에서 병렬 http 요청 작업을 수행하고 asyncio싶지만 python-requests의 이벤트 루프를 차단합니다 asyncio. aiohttp를 찾았 지만 http 프록시를 사용하여 http 요청 서비스를 제공 할 수 없습니다.

그래서의 도움으로 비동기 http 요청을 수행하는 방법이 있는지 알고 싶습니다 asyncio.


요청 (또는 다른 차단 라이브러리)을 asyncio와 함께 사용하려면 BaseEventLoop.run_in_executor사용 하여 다른 스레드에서 함수를 실행하고 함수를 생성하여 결과를 얻을 수 있습니다. 예를 들면 다음과 같습니다.

import asyncio
import requests

@asyncio.coroutine
def main():
    loop = asyncio.get_event_loop()
    future1 = loop.run_in_executor(None, requests.get, 'http://www.google.com')
    future2 = loop.run_in_executor(None, requests.get, 'http://www.google.co.uk')
    response1 = yield from future1
    response2 = yield from future2
    print(response1.text)
    print(response2.text)

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

이것은 두 응답을 동시에 얻을 것입니다.

Python 3.5에서는 새로운 await/ async구문을 사용할 수 있습니다 .

import asyncio
import requests

async def main():
    loop = asyncio.get_event_loop()
    future1 = loop.run_in_executor(None, requests.get, 'http://www.google.com')
    future2 = loop.run_in_executor(None, requests.get, 'http://www.google.co.uk')
    response1 = await future1
    response2 = await future2
    print(response1.text)
    print(response2.text)

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

자세한 내용은 PEP0492참조하십시오 .


aiohttp 는 이미 HTTP 프록시와 함께 사용할 수 있습니다 :

import asyncio
import aiohttp


@asyncio.coroutine
def do_request():
    proxy_url = 'http://localhost:8118'  # your proxy address
    response = yield from aiohttp.request(
        'GET', 'http://google.com',
        proxy=proxy_url,
    )
    return response

loop = asyncio.get_event_loop()
loop.run_until_complete(do_request())

위의 답변은 여전히 ​​구식 Python 3.4 스타일 코 루틴을 사용하고 있습니다. Python 3.5 이상을 사용하면 다음과 같이 작성합니다.

aiohttp http 프록시를 지원합니다

import aiohttp
import asyncio

async def fetch(session, url):
    async with session.get(url) as response:
        return await response.text()

async def main():
    urls = [
            'http://python.org',
            'https://google.com',
            'http://yifei.me'
        ]
    tasks = []
    async with aiohttp.ClientSession() as session:
        for url in urls:
            tasks.append(fetch(session, url))
        htmls = await asyncio.gather(*tasks)
        for html in htmls:
            print(html[:100])

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())

요청은 현재 지원하지 않으며 asyncio그러한 지원을 제공 할 계획이 없습니다. 사용 방법을 알고 있는 사용자 지정 "전송 어댑터"( 여기 에서 설명 )를 구현할 수 있습니다 asyncio.

내가 시간을 갖고 있으면 실제로 살펴볼 수도 있지만 약속 할 수는 없습니다.


Pimin Konstantin Kefaloukos의 기사에 async / await 루프 및 스레딩이 좋은 경우가 있습니다. Python 및 asyncio를 사용한 쉬운 병렬 HTTP 요청 :

To minimize the total completion time, we could increase the size of the thread pool to match the number of requests we have to make. Luckily, this is easy to do as we will see next. The code listing below is an example of how to make twenty asynchronous HTTP requests with a thread pool of twenty worker threads:

# Example 3: asynchronous requests with larger thread pool
import asyncio
import concurrent.futures
import requests

async def main():

    with concurrent.futures.ThreadPoolExecutor(max_workers=20) as executor:

        loop = asyncio.get_event_loop()
        futures = [
            loop.run_in_executor(
                executor, 
                requests.get, 
                'http://example.org/'
            )
            for i in range(20)
        ]
        for response in await asyncio.gather(*futures):
            pass


loop = asyncio.get_event_loop()
loop.run_until_complete(main())

참고URL : https://stackoverflow.com/questions/22190403/how-could-i-use-requests-in-asyncio

반응형