Die map eines Pools übergibt dem Worker jeweils ein Element. Machen Sie dieses Element zu einem vollständigen Job, einschließlich URL und ausgewähltem Proxy, damit der Worker seine Route nicht aus einer sich ändernden globalen Liste ableitet.

Für eine endliche Anzahl von urls geben Sie eine nicht leere Liste validierter Proxy-URLs an. Öffentliche HTTP-Kandidaten finden Sie in der HTTP-Proxy-Liste:

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 und handle_result werden von der Anwendung bereitgestellt. Der Koordinator weist Endpunkte in wiederholter Reihenfolge zu; jeder Worker erhält ein festes Paar. Das Iterieren über die Ergebnisse macht auch Worker-Ausnahmen sichtbar.

Fünf Worker begrenzen aktive Jobs, nicht aktive Jobs pro Proxy. Hat die Liste zwei Endpunkte, können mehrere Jobs denselben Endpunkt gleichzeitig nutzen. Fügen Sie bei Bedarf eine separate Kapazitätsregel pro Endpunkt hinzu. Für einen aktiven Job pro Endpunkt-URL kann eine synchronisierte Warteschlangen-Leihe jeden Eintrag reservieren und zurückgeben.

Ein Wiederholungsversuch sollte einen neuen begrenzten Versuch für dieselbe URL erzeugen. Vermeiden Sie rekursive Wiederholungsaufrufe, die Einträge aus einer gemeinsam genutzten Liste entfernen: Ein anderer Worker wählt möglicherweise daraus aus, und eine erschöpfte Liste braucht dennoch ein ausdrückliches Ergebnis.

Ähnliche Artikel