Recoger cada resultado de solicitudes proxy urllib3 concurrentes
Comparte un ProxyManager configurado entre hilos de trabajo, consume el iterador de resultados del ejecutor y distingue la retención del grupo de un límite de conexiones.
Crear un grupo de trabajadores no entrega al llamador las páginas descargadas. Conserva y consume los valores que devuelve el trabajo enviado:
from concurrent.futures import ThreadPoolExecutor
import urllib3
manager = urllib3.ProxyManager(
'http://proxy.example:8080',
maxsize=4,
block=True,
)
def fetch(url):
response = manager.request(
'GET', url, timeout=urllib3.Timeout(connect=5, read=15),
)
return url, response.status, response.data
try:
with ThreadPoolExecutor(max_workers=4) as workers:
results = list(workers.map(fetch, urls))
finally:
manager.clear()Este fragmento supone una lista limitada de URL y tamaños de respuesta ordinarios. Para comprobaciones de URL públicas permitidas sin autenticación de proxy, un candidato de la lista de proxies HTTP puede sustituir el extremo HTTP de ejemplo del gestor. Cada resultado incluye su URL para que el llamador pueda asociar el estado y el cuerpo con la solicitud correcta. map devuelve los resultados en el orden de entrada; una excepción en un trabajador se lanza cuando se recupera ese resultado.
El ProxyManager configurado posee la agrupación de conexiones para las solicitudes. Con el modo de respuesta precargada predeterminado que se usa aquí, urllib3 lee el cuerpo y devuelve la conexión a su grupo. Una versión en streaming necesitaría un consumo explícito y la liberación de la conexión.
maxsize normalmente controla las conexiones reutilizables retenidas, no un límite estricto para cada socket abierto. block=True cambia el comportamiento relevante del grupo para que los llamadores esperen una conexión libre en lugar de abrir otras adicionales por encima del límite de ese grupo.
El número de trabajadores limita las llamadas concurrentes en este ejemplo. Con muchos destinos, también importan la disposición del grupo y la ruta usada para los túneles HTTPS; un ajuste por grupo no debe describirse como una cuota global de sockets para cada host.