Прикупљање сваког резултата из паралелних urllib3 прокси захтева
Поделите конфигурисани ProxyManager између радних нити, трошите итератор резултата извршиоца и разликујте задржавање у базену од ограничења веза.
Прављење радног базена не даје позиваоцу преузете странице. Сачувајте и трошите вредности које враћа послати посао:
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()Овај фрагмент претпоставља ограничену листу URL-ова и уобичајене величине одговора. За дозвољене провере јавних URL-ова без прокси аутентификације, кандидат са листе HTTP проксија може заменити пример HTTP крајње тачке менаџера. Сваки резултат укључује свој URL како би позивалац могао да повеже статус и тело са исправним захтевом. map враћа резултате по редоследу уноса; изузетак у раднику се подиже када се тај резултат преузме.
Конфигурисани ProxyManager поседује базен веза за захтеве. Уз овде коришћени подразумевани режим унапред учитаног одговора, urllib3 чита тело и враћа везу у свој базен. Верзија са стримовањем би захтевала експлицитну потрошњу и ослобађање везе.
maxsize обично контролише задржане вишекратно употребљиве везе, а не тврдо ограничење на сваки отворени сокет. block=True мења релевантно понашање базена тако да позиваоци чекају слободну везу уместо да отварају додатне изнад ограничења тог базена.
Број радника ограничава паралелне позиве у овом примеру. Са много одредишта, распоред базена и рута која се користи за HTTPS тунеле такође су важни; подешавање једног базена не треба описивати као једну глобалну квоту сокета за сваког домаћина.