تابع 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 ایجاد کند. از فراخوانی‌های بازگشتی تلاش مجدد که ورودی‌ها را از یک فهرست مشترک حذف می‌کنند بپرهیزید: ممکن است کارگر دیگری از آن انتخاب کند، و فهرست تهی‌شده هنوز به یک نتیجه صریح نیاز دارد.

مقالات مرتبط