Створення пулу робітників не передає викликачу завантажені сторінки. Зберігайте та споживайте значення, які повертає надіслана робота:

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; налаштування одного пулу не слід описувати як єдину глобальну квоту сокетів для кожного хоста.

Схожі статті