파이썬 요청 라이브러리 문서에 제공된 샘플을 사용해 보았습니다 .
로 async.map(rs)
응답 코드를 얻었지만 요청 된 각 페이지의 내용을 가져오고 싶습니다. 예를 들어 이것은 작동하지 않습니다.
out = async.map(rs)
print out[0].content
requests-threads
지금 존재하는 것 같습니다 .
파이썬 요청 라이브러리 문서에 제공된 샘플을 사용해 보았습니다 .
로 async.map(rs)
응답 코드를 얻었지만 요청 된 각 페이지의 내용을 가져오고 싶습니다. 예를 들어 이것은 작동하지 않습니다.
out = async.map(rs)
print out[0].content
requests-threads
지금 존재하는 것 같습니다 .
답변:
아래 답변은 v0.13.0 + 요청 에는 적용 되지 않습니다 . 이 질문이 작성된 후 비동기 기능이 grequests 로 이동되었습니다 . 그러나, 당신은 대체 할 수 requests
와 함께 grequests
아래 그것은 작동합니다.
<v0.13.0 요청 사용에 관한 원래 질문을 반영하기 위해이 답변을 그대로 두었습니다.
async.map
비동기 적으로 여러 작업을 수행하려면 다음을 수행 해야합니다.
async.map
모든 요청 / 조치 목록에서 전화예:
from requests import async
# If using requests > v0.13.0, use
# from grequests import async
urls = [
'http://python-requests.org',
'http://httpbin.org',
'http://python-guide.org',
'http://kennethreitz.com'
]
# A simple task to do to each response object
def do_something(response):
print response.url
# A list to hold our things to do via async
async_list = []
for u in urls:
# The "hooks = {..." part is where you define what you want to do
#
# Note the lack of parentheses following do_something, this is
# because the response will be used as the first argument automatically
action_item = async.get(u, hooks = {'response' : do_something})
# Add the task to our list of things to do via async
async_list.append(action_item)
# Do our list of things to do via async
async.map(async_list)
from grequests import async
하지 작업 .. 나를 위해 일을 해봐요의 정의를 이렇게 def do_something(response, **kwargs):
, 나는에서 찾을 stackoverflow.com/questions/15594015/...
from requests import async
하여 교체 import grequests as async
했습니다.
async
이제 독립 모듈 grequests
입니다.
여기를 참조하십시오 : https://github.com/kennethreitz/grequests
그리고 거기에 : 파이썬을 통해 여러 HTTP 요청을 보내는 이상적인 방법은 무엇입니까?
$ pip install grequests
스택을 빌드하십시오.
import grequests
urls = [
'http://www.heroku.com',
'http://tablib.org',
'http://httpbin.org',
'http://python-requests.org',
'http://kennethreitz.com'
]
rs = (grequests.get(u) for u in urls)
스택을 보내
grequests.map(rs)
결과는 다음과 같습니다
[<Response [200]>, <Response [200]>, <Response [200]>, <Response [200]>, <Response [200]>]
grequests는 동시 요청에 대한 제한을 설정하지 않는 것 같습니다 (예 : 여러 요청이 동일한 서버로 전송되는 경우).
results = grequests.map(rs)
다음은이 라인 이후의 코드는 블록을, 나는 비동기 효과를 볼 수 있습니까?
나는 request-futures 와 grequests를 테스트 했습니다 . Grequests는 빠르지 만 원숭이 패치 및 종속성과 관련된 추가 문제가 발생합니다. requests-futures는 grequest보다 몇 배 느립니다. 나는 내 자신을 작성하고 간단하게 요청을 ThreadPoolExecutor에 래핑하기로 결정했으며 그 요청 은 거의 빠르지 만 외부 종속성은 없었습니다.
import requests
import concurrent.futures
def get_urls():
return ["url1","url2"]
def load_url(url, timeout):
return requests.get(url, timeout = timeout)
with concurrent.futures.ThreadPoolExecutor(max_workers=20) as executor:
future_to_url = {executor.submit(load_url, url, 10): url for url in get_urls()}
for future in concurrent.futures.as_completed(future_to_url):
url = future_to_url[future]
try:
data = future.result()
except Exception as exc:
resp_err = resp_err + 1
else:
resp_ok = resp_ok + 1
어쩌면 요청-선물은 또 다른 선택이다.
from requests_futures.sessions import FuturesSession
session = FuturesSession()
# first request is started in background
future_one = session.get('http://httpbin.org/get')
# second requests is started immediately
future_two = session.get('http://httpbin.org/get?foo=bar')
# wait for the first request to complete, if it hasn't already
response_one = future_one.result()
print('response one status: {0}'.format(response_one.status_code))
print(response_one.content)
# wait for the second request to complete, if it hasn't already
response_two = future_two.result()
print('response two status: {0}'.format(response_two.status_code))
print(response_two.content)
사무실 문서 에도 권장됩니다 . gevent를 포함하고 싶지 않다면 좋은 것입니다.
ThreadPoolExecutor(max_workers=10)
게시 된 대부분의 답변에 많은 문제가 있습니다. 제한된 기능으로 포팅 된 더 이상 사용되지 않는 라이브러리를 사용하거나 요청 실행에 너무 많은 마술을 제공하여 오류 처리가 어렵습니다. 위의 카테고리 중 하나에 속하지 않으면 타사 라이브러리이거나 더 이상 사용되지 않습니다.
일부 솔루션은 순수하게 http 요청에서 정상적으로 작동하지만 솔루션은 다른 종류의 요청에 대해서는 부족합니다. 여기에는 고도로 맞춤화 된 솔루션이 필요하지 않습니다.
파이썬 내장 라이브러리를 사용하면 asyncio
모든 유형의 비동기 요청을 수행하기에 충분할뿐만 아니라 복잡하고 사용 사례 별 오류 처리에 충분한 유동성을 제공 할 수 있습니다.
import asyncio
loop = asyncio.get_event_loop()
def do_thing(params):
async def get_rpc_info_and_do_chores(id):
# do things
response = perform_grpc_call(id)
do_chores(response)
async def get_httpapi_info_and_do_chores(id):
# do things
response = requests.get(URL)
do_chores(response)
async_tasks = []
for element in list(params.list_of_things):
async_tasks.append(loop.create_task(get_chan_info_and_do_chores(id)))
async_tasks.append(loop.create_task(get_httpapi_info_and_do_chores(ch_id)))
loop.run_until_complete(asyncio.gather(*async_tasks))
작동 방식은 간단합니다. 비동기 적으로 발생하는 일련의 작업을 만든 다음 해당 작업을 실행하고 완료되면 종료하도록 루프를 요청합니다. 추가 라이브러리는 유지 관리 부족, 기능 부족이 필요하지 않습니다.
async
합니다. 그런 다음 예를 들어 할 수 있습니다 await response = requests.get(URL)
. 아니?
requests
URL 목록을 동기식으로 호출하는 것보다 훨씬 빠릅니다 (어떤 경우에는 느리다). 예를 들어, 위의 전략을 사용하여 10 번 응답하는 데 3 초가 걸리는 엔드 포인트를 요청하는 데 약 30 초가 소요됩니다. 진정한 async
성능 을 원한다면 과 같은 것을 사용해야합니다 aiohttp
.
run_until_complete
. 스레드 모듈을 사용하지 않으면 OS 계층에 비동기를 위임합니다. 자세한 내용은 파이썬에서 GIL 문제를 읽어보십시오
나는 이것이 한동안 폐쇄되었다는 것을 알고 있지만 요청 라이브러리에 구축 된 다른 비동기 솔루션을 홍보하는 것이 유용 할 수 있다고 생각했습니다.
list_of_requests = ['http://moop.com', 'http://doop.com', ...]
from simple_requests import Requests
for response in Requests().swarm(list_of_requests):
print response.content
문서는 다음과 같습니다. http://pythonhosted.org/simple-requests/
threads=list()
for requestURI in requests:
t = Thread(target=self.openURL, args=(requestURI,))
t.start()
threads.append(t)
for thread in threads:
thread.join()
...
def openURL(self, requestURI):
o = urllib2.urlopen(requestURI, timeout = 600)
o...
당신이 asyncio 사용하려면, 다음 requests-async
을 위해 비동기 / await를 기능을 제공합니다 requests
- https://github.com/encode/requests-async
나는 얼마 동안 github의 gist API에 대한 비동기 호출을 위해 python 요청을 사용하고 있습니다.
예를 들어 여기 코드를 참조하십시오.
https://github.com/davidthewatson/flasgist/blob/master/views.py#L60-72
이 스타일의 파이썬은 가장 명확한 예는 아니지만 코드가 작동한다는 것을 확신 할 수 있습니다. 이것이 혼란 스러운지 알려 주시면 문서화하겠습니다.
사용할 수 있습니다 httpx
.
import httpx
async def get_async(url):
async with httpx.AsyncClient() as client:
return await client.get(url)
urls = ["http://google.com", "http://wikipedia.org"]
# Note that you need an async context to use `await`.
await asyncio.gather(*map(get_async, urls))
기능적인 구문을 원한다면 gamla lib가 이것을로 묶 습니다 get_async
.
그럼 넌 할 수있어
await gamla.map(gamla.get_async(10), ["http://google.com", "http://wikipedia.org"])
는 10
초 제한 시간입니다.
(면책 조항 : 나는 저자입니다)
나는 파이썬에서 비동기 메소드를 사용하여 몇 가지를 시도했지만 비동기 프로그래밍을 위해 트위스트를 사용하는 것이 훨씬 더 운이 좋았습니다. 문제가 적으며 문서화가 잘되어 있습니다. 여기 당신이 꼬이려고하는 것에 simmilar 무언가의 링크가 있습니다.
http://pythonquirks.blogspot.com/2011/04/twisted-asynchronous-http-request.html