Saltar al contenido

Solicitudes asíncronas con solicitudes de Python

Posteriormente a observar en diferentes repositorios y sitios webs al terminar nos encontramos con la solución que te compartiremos aquí.

Solución:

Nota

La siguiente respuesta es no aplicable a solicitudes v0.13.0+. La funcionalidad asíncrona se trasladó a grequests después de escribir esta pregunta. Sin embargo, podría simplemente reemplazar requests con grequests a continuación y debería funcionar.

Dejé esta respuesta tal como está para reflejar la pregunta original sobre el uso de solicitudes < v0.13.0.


Para hacer varias tareas con async.mapasincrónicamente tienes que:

  1. Define una función para lo que quieres hacer con cada objeto (tu tarea)
  2. Agregue esa función como un gancho de evento en su solicitud
  3. Llamar 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)

async ahora es un módulo independiente: grequests.

Ver aquí: https://github.com/kennethreitz/grequests

Y allí: ¿Método ideal para enviar múltiples solicitudes HTTP a través de 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)

el resultado parece

[, , , , ]

grequests no parece establecer una limitación para las solicitudes simultáneas, es decir, cuando se envían varias solicitudes al mismo servidor.

Probé ambas solicitudes, futuros y grequests. Grequests es más rápido pero trae parches mono y problemas adicionales con las dependencias. request-futures es varias veces más lento que grequests. Decidí escribir las mías y simplemente envolví las solicitudes en ThreadPoolExecutor y fue casi tan rápido como las solicitudes grequest, 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

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *