Crear un pool de traballadores non entrega ao chamador as páxinas descargadas. Conserva e consume os valores que devolve o traballo 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 supón unha lista limitada de URL e tamaños de resposta habituais. Para comprobacións de URL públicas permitidas sen autenticación de proxy, un candidato da lista de proxies HTTP pode substituír o extremo HTTP de exemplo do xestor. Cada resultado inclúe o seu URL para que o chamador poida asociar o estado e o corpo coa solicitude correcta. map devolve os resultados na orde de entrada; unha excepción nun traballador lánzase cando se recupera ese resultado.

O ProxyManager configurado posúe a agrupación de conexións para as solicitudes. Co modo de resposta precargada predeterminado usado aquí, urllib3 le o corpo e devolve a conexión ao seu pool. Unha versión en streaming necesitaría un consumo explícito e a liberación da conexión.

maxsize normalmente controla as conexións reutilizables retidas, non un límite estrito para cada socket aberto. block=True cambia o comportamento relevante do pool para que os chamadores esperen unha conexión libre en lugar de abrir outras adicionais por riba do límite dese pool.

O número de traballadores limita as chamadas simultáneas neste exemplo. Con moitos destinos, tamén importan a disposición do pool e a ruta usada para os túneles HTTPS; un axuste por pool non debe describirse como unha cota global de sockets para cada host.

Artigos relacionados