map fondu předává pracovníkovi vždy jednu položku. Udělejte z této položky úplnou úlohu včetně URL a vybrané proxy, aby pracovník neodvozoval svou trasu z měnícího se globálního seznamu.

Pro konečné urls poskytněte neprázdný seznam ověřených URL proxy. Veřejní kandidáti HTTP jsou k dispozici v seznamu HTTP proxy:

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 a handle_result dodává aplikace. Koordinátor přiřazuje koncové body v opakujícím se pořadí; každý pracovník dostane jeden pevný pár. Iterování výsledků také odhalí výjimky pracovníků.

Pět pracovníků omezuje aktivní úlohy, nikoli aktivní úlohy na proxy. Pokud má seznam dva koncové body, může několik úloh používat stejný koncový bod současně. Když je to potřeba, přidejte samostatné pravidlo kapacity pro každý koncový bod. Pro jednu aktivní úlohu na URL koncového bodu může synchronizovaný pronájem fronty rezervovat a vracet každou položku.

Opakování by mělo vytvořit nový omezený pokus pro stejnou URL. Vyhněte se rekurzivním voláním opakování, která odebírají položky ze sdíleného seznamu: jiný pracovník z něj může vybírat a vyčerpaný seznam stále potřebuje výslovný výsledek.

Související články