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. Избегавајте рекурзивне позиве поновног покушаја који уклањају уносе из заједничке листе: други радник можда бира из ње, а исцрпљена листа и даље захтева јасан исход.

Повезани чланци