[python] asyncio에서 요청을 어떻게 사용할 수 있습니까?
에서 병렬 http 요청 작업을 수행하고 asyncio
싶지만 python-requests
이벤트 루프를 차단할 수 asyncio
있습니다. aiohttp를 찾았 지만 http 프록시를 사용하여 http 요청 서비스를 제공 할 수 없습니다.
따라서 .NET의 도움으로 비동기 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에서는 new 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 요청 :
총 완료 시간을 최소화하기 위해 요청 수에 맞게 스레드 풀의 크기를 늘릴 수 있습니다. 운 좋게도 다음에서 볼 수 있듯이 쉽게 수행 할 수 있습니다. 아래 코드 목록은 20 개의 작업자 스레드로 구성된 스레드 풀을 사용하여 20 개의 비동기 HTTP 요청을 만드는 방법의 예입니다.
# 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())