Zbieranie każdego wyniku ze współbieżnych żądań proxy urllib3
Udostępnij skonfigurowany ProxyManager między wątkami roboczymi, zużywaj iterator wyników wykonawcy i odróżniaj utrzymywanie puli od limitu połączeń.
Utworzenie puli procesów roboczych nie przekazuje wywołującemu pobranych stron. Zachowaj i zużywaj wartości zwracane przez przesłaną pracę:
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()Ten fragment zakłada ograniczoną listę adresów URL i typowe rozmiary odpowiedzi. W przypadku dozwolonych kontroli publicznych adresów URL bez uwierzytelniania proxy kandydat z listy proxy HTTP może zastąpić przykładowy punkt końcowy HTTP menedżera. Każdy wynik zawiera swój adres URL, aby wywołujący mógł powiązać stan i treść z właściwym żądaniem. map zwraca wyniki w kolejności wejściowej; wyjątek w wątku roboczym jest zgłaszany, gdy ten wynik jest pobierany.
Skonfigurowany ProxyManager posiada pulę połączeń dla żądań. W używanym tutaj domyślnym trybie wstępnie wczytanej odpowiedzi urllib3 odczytuje treść i zwraca połączenie do swojej puli. Wersja strumieniowa wymagałaby jawnego zużycia i zwolnienia połączenia.
maxsize zwykle kontroluje utrzymywane połączenia wielokrotnego użytku, a nie twardy limit każdego otwartego gniazda. block=True zmienia odpowiednie zachowanie puli, aby wywołujący czekali na wolne połączenie zamiast otwierać dodatkowe ponad limit tej puli.
Liczba wątków roboczych ogranicza współbieżne wywołania w tym przykładzie. Przy wielu miejscach docelowych znaczenie mają także układ puli i trasa używana dla tuneli HTTPS; ustawienia jednej puli nie należy opisywać jako jednego globalnego limitu gniazd dla każdego hosta.