Attribuer une URL et un proxy à chaque tâche Python ThreadPoolExecutor
Attribuez un proxy avant de soumettre une tâche de requête Python au lieu de laisser les workers se disputer un état de sélection partagé et mutable.
Le map d'un pool transmet un élément au worker à la fois. Faites de cet élément une tâche complète, incluant l'URL et le proxy sélectionné, afin que le worker ne déduise pas son itinéraire d'une liste globale changeante.
Pour un nombre fini d'urls, fournissez une liste non vide d'URL de proxy validées. Des candidats HTTP publics sont disponibles dans la liste de proxys 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 et handle_result sont fournis par l'application. Le coordinateur attribue les points de terminaison dans un ordre répétitif ; chaque worker reçoit une paire fixe. L'itération des résultats fait aussi apparaître les exceptions des workers.
Cinq workers limitent les tâches actives, pas les tâches actives par proxy. Si la liste contient deux points de terminaison, plusieurs tâches peuvent utiliser le même point de terminaison simultanément. Ajoutez une règle de capacité distincte par point de terminaison lorsque c'est nécessaire. Pour une tâche active par URL de point de terminaison, un bail de file synchronisé peut réserver et restituer chaque entrée.
Une nouvelle tentative doit créer une tentative bornée pour la même URL. Évitez les appels de nouvelle tentative récursifs qui retirent des entrées d'une liste partagée : un autre worker peut être en train d'y choisir, et une liste épuisée a toujours besoin d'un résultat explicite.