map на пула предава по един елемент на работника. Направете този елемент пълна задача, включително URL и избрания прокси, така че работникът да не извежда маршрута си от променлив глобален списък.

За краен брой urls предоставете непразен списък с валидирани URL на прокси. Публичните HTTP кандидати са налични в списъка с HTTP прокси:

from concurrent.futures import ThreadPoolExecutor
from itertools import cycle
import requests

def fetch(job):
    url, proxy_url = job
    proxies = {"http": proxy_url, "https": proxy_url}
    with requests.get(url, proxies=proxies, timeout=(5, 15)) as response:
        response.raise_for_status()
        return url, response.text

if not proxy_urls:
    raise ValueError("No proxy endpoints were supplied")

jobs = zip(urls, cycle(proxy_urls))
with ThreadPoolExecutor(max_workers=5) as executor:
    for url, body in executor.map(fetch, jobs):
        handle_result(url, body)

urls, proxy_urls и handle_result се предоставят от приложението. Координаторът задава крайни точки в повтарящ се ред; всеки работник получава една фиксирана двойка. Итерирането на резултатите също показва изключенията на работниците.

Пет работника ограничават активните задачи, а не активните задачи на прокси. Ако списъкът има две крайни точки, няколко задачи могат да използват една и съща крайна точка едновременно. Добавете отделно правило за капацитет на крайна точка, когато е необходимо. За една активна задача на URL на крайна точка, синхронизиран наем на опашка може да резервира и връща всеки запис.

Повторният опит трябва да създава нов ограничен опит за същия URL. Избягвайте рекурсивни извиквания за повторен опит, които премахват записи от споделен списък: друг работник може да избира от него, а изчерпан списък все още се нуждае от ясен резултат.

Подобни статии