파이썬 요청 라이브러리 문서에 제공된 샘플을 사용해 보았습니다 .
로 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). 아니?
requestsURL 목록을 동기식으로 호출하는 것보다 훨씬 빠릅니다 (어떤 경우에는 느리다). 예를 들어, 위의 전략을 사용하여 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