Samla varje resultat från samtidiga urllib3-proxyförfrågningar
Dela en konfigurerad ProxyManager mellan arbetstrådar, konsumera utförarens resultatiterator och skilj poolbehållning från en anslutningsgräns.
Att skapa en arbetarpool ger inte anroparen de nedladdade sidorna. Behåll och konsumera de värden som det inskickade arbetet returnerar:
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()Detta utdrag förutsätter en begränsad URL-lista och vanliga svarsstorlekar. För tillåtna offentliga URL-kontroller utan proxyautentisering kan en kandidat från HTTP-proxylistan ersätta hanterarens exempel-HTTP-slutpunkt. Varje resultat innehåller sin URL så att anroparen kan koppla status och brödtext till rätt begäran. map returnerar resultat i inmatningsordning; ett undantag i en arbetare kastas när det resultatet hämtas.
Den konfigurerade ProxyManager äger anslutningspoolen för förfrågningarna. Med det förvalda förinlästa svarsläget som används här läser urllib3 brödtexten och returnerar anslutningen till sin pool. En strömmande version skulle behöva explicit konsumtion och frigöring av anslutningen.
maxsize styr normalt behållna återanvändbara anslutningar, inte en hård gräns för varje öppnad socket. block=True ändrar det relevanta poolbeteendet så att anropare väntar på en ledig anslutning i stället för att öppna ytterligare utöver den poolens gräns.
Antalet arbetare begränsar samtidiga anrop i detta exempel. Med många destinationer spelar även poolens utformning och rutten för HTTPS-tunnlar roll; en inställning per pool bör inte beskrivas som en global socketkvot för varje värd.