requests - Solicitudes asincrónicas con solicitudes de Python
requests python timeout default (8)
Nota
La respuesta a continuación no es aplicable a las solicitudes v0.13.0 +. La funcionalidad asincrónica se movió a grequests después de grequests esta pregunta. Sin embargo, podría reemplazar las requests
con grequests
siguientes y debería funcionar.
Dejé esta respuesta como está para reflejar la pregunta original que era sobre el uso de solicitudes <v0.13.0.
Para realizar varias tareas con async.map
asincrónicamente, debes:
- Defina una función para lo que quiere hacer con cada objeto (su tarea)
- Agregue esa función como un gancho de evento en su solicitud
- Llame a
async.map
en una lista de todas las solicitudes / acciones
Ejemplo:
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)
Probé la muestra provista en la documentación de la biblioteca de solicitudes para Python:
http://docs.python-requests.org/en/latest/user/advanced/#asynchronous-requests
con async.map(rs)
obtengo los códigos de respuesta, pero quiero obtener el contenido de cada página solicitada.
out = async.map(rs)
print out[0].content
por ejemplo, simplemente no está funcionando.
He estado usando solicitudes de Python para llamadas asincrónicas en contra de la API de github durante un tiempo.
Para un ejemplo, mira el código aquí:
https://github.com/davidthewatson/flasgist/blob/master/views.py#L60-72
Este estilo de pitón puede no ser el mejor ejemplo, pero puedo asegurarte que el código funciona. Avíseme si esto lo confunde y lo documentaré.
Sé que esto ha estado cerrado por un tiempo, pero pensé que podría ser útil promover otra solución asíncrona integrada en la biblioteca de solicitudes.
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
Los documentos están aquí: http://pythonhosted.org/simple-requests/
También he intentado algunas cosas usando los métodos asíncronos en Python, sin embargo, he tenido mucha mejor suerte al utilizar Twisted para la programación asincrónica. Tiene menos problemas y está bien documentado. Aquí hay un enlace de algo similar a lo que está intentando en retorcido.
http://pythonquirks.blogspot.com/2011/04/twisted-asynchronous-http-request.html
tal vez requests-futures es otra opción.
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)
También se recomienda en el documento de la oficina . Si no quieres involucrar a gevent, es bueno.
async
ahora es un módulo independiente: grequests
.
Vea aquí: grequests
Y ahí: ¿ Método ideal para enviar múltiples solicitudes HTTP sobre Python?
instalación:
$ pip install grequests
uso:
construir una pila:
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)
enviar la pila
grequests.map(rs)
resultado parece
[<Response [200]>, <Response [200]>, <Response [200]>, <Response [200]>, <Response [200]>]
las solicitudes no parecen establecer una limitación para las solicitudes concurrentes, es decir, cuando se envían varias solicitudes al mismo servidor.
Probé ambas solicitudes, futuros y solicitudes . Grequests es más rápido pero trae parches de mono y problemas adicionales con dependencias. solicitudes-futuros es varias veces más lento que las solicitudes. Decidí escribir mis propias y simplemente envueltas solicitudes en ThreadPollExecutor y fue casi tan rápido como grequests, pero sin dependencias externas.
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
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...