Prikupljanje svakog rezultata iz paralelnih urllib3 proxy zahtjeva
Podijelite konfigurisani ProxyManager između radnih niti, trošite iterator rezultata izvršavaoca i razlikujte zadržavanje u bazenu od ograničenja veza.
Kreiranje radnog bazena ne daje pozivaocu preuzete stranice. Sačuvajte i trošite vrijednosti koje vraća poslani posao:
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()Ovaj fragment pretpostavlja ograničenu listu URL-ova i uobičajene veličine odgovora. Za dozvoljene provjere javnih URL-ova bez proxy autentifikacije, kandidat sa liste HTTP proxyja može zamijeniti primjer HTTP krajnje tačke menadžera. Svaki rezultat uključuje svoj URL kako bi pozivalac mogao povezati status i tijelo s ispravnim zahtjevom. map vraća rezultate u redoslijedu unosa; izuzetak u radniku se podiže kada se taj rezultat preuzme.
Konfigurisani ProxyManager posjeduje bazen veza za zahtjeve. Uz ovdje korišteni zadani način unaprijed učitanog odgovora, urllib3 čita tijelo i vraća vezu u svoj bazen. Streaming verzija bi zahtijevala eksplicitnu potrošnju i oslobađanje veze.
maxsize obično kontroliše zadržane višekratno upotrebljive veze, a ne tvrdo ograničenje na svaki otvoreni socket. block=True mijenja relevantno ponašanje bazena tako da pozivaoci čekaju slobodnu vezu umjesto da otvaraju dodatne iznad ograničenja tog bazena.
Broj radnika ograničava paralelne pozive u ovom primjeru. S mnogo odredišta, raspored bazena i ruta koja se koristi za HTTPS tunele također su važni; postavka jednog bazena ne treba se opisivati kao jedna globalna kvota soketa za svakog hosta.