Raccogliere ogni risultato dalle richieste proxy urllib3 concorrenti
Condividi un ProxyManager configurato tra i thread di lavoro, consuma l'iteratore dei risultati dell'esecutore e distingui la ritenzione del pool da un limite di connessioni.
Creare un pool di lavoratori non consegna al chiamante le pagine scaricate. Conserva e consuma i valori restituiti dal lavoro inviato:
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()Questo frammento presuppone un elenco limitato di URL e dimensioni di risposta ordinarie. Per i controlli URL pubblici consentiti senza autenticazione proxy, un candidato dall'elenco di proxy HTTP può sostituire l'endpoint HTTP di esempio del gestore. Ogni risultato include il suo URL così il chiamante può associare stato e corpo alla richiesta corretta. map restituisce i risultati nell'ordine di input; un'eccezione in un lavoratore viene sollevata quando quel risultato viene recuperato.
Il ProxyManager configurato possiede il pooling delle connessioni per le richieste. Con la modalità di risposta precaricata predefinita usata qui, urllib3 legge il corpo e restituisce la connessione al suo pool. Una versione in streaming richiederebbe un consumo esplicito e il rilascio della connessione.
maxsize normalmente controlla le connessioni riutilizzabili mantenute, non un limite rigido su ogni socket aperto. block=True modifica il comportamento del pool interessato affinché i chiamanti attendano una connessione libera invece di aprirne altre oltre il limite di quel pool.
Il numero di lavoratori limita le chiamate concorrenti in questo esempio. Con molte destinazioni contano anche la disposizione del pool e la rotta usata per i tunnel HTTPS; un'impostazione per pool non va descritta come un'unica quota globale di socket per ogni host.