map i një grupi i kalon punëtorit një artikull në një herë. Bëje atë artikull një punë të plotë, duke përfshirë URL-në dhe proxy-n e zgjedhur, që punëtori të mos e nxjerrë rrugën e tij nga një listë globale që ndryshon.

Për urls të fundme, jep një listë jo të zbrazët me URL proxy të validuara. Kandidatët publikë HTTP janë të disponueshëm në listën e proxy-ve 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 dhe handle_result jepen nga aplikacioni. Koordinatori cakton pikat fundore në një rend të përsëritur; çdo punëtor merr një çift fiks. Përsëritja e rezultateve nxjerr gjithashtu përjashtimet e punëtorëve.

Pesë punëtorë kufizojnë punët aktive, jo punët aktive për proxy. Nëse lista ka dy pika fundore, disa punë mund të përdorin të njëjtën pikë fundore njëkohësisht. Shto një rregull të veçantë kapaciteti për çdo pikë fundore kur kërkohet. Për një punë aktive për URL pikë fundore, një qiradhënie e radhës së sinkronizuar mund të rezervojë dhe të kthejë çdo hyrje.

Një riprovim duhet të krijojë një provë të re të kufizuar për të njëjtën URL. Shmang thirrjet rekursive të riprovimit që heqin hyrje nga një listë e përbashkët: një punëtor tjetër mund të jetë duke zgjedhur prej saj, dhe një listë e shteruar ende kërkon një rezultat të qartë.

Artikuj të ngjashëm