Asignar una URL y un proxy a cada tarea de Python ThreadPoolExecutor
Asigna un proxy antes de enviar una tarea de solicitud de Python en lugar de dejar que los trabajadores compitan por un estado de selección compartido y mutable.
El map de un pool pasa un elemento al trabajador cada vez. Convierte ese elemento en una tarea completa, incluida la URL y el proxy seleccionado, para que el trabajador no deduzca su ruta de una lista global cambiante.
Para un número finito de urls, proporciona una lista no vacía de URL de proxy validadas. Los candidatos HTTP públicos están disponibles en la lista de proxies 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 y handle_result los proporciona la aplicación. El coordinador asigna los puntos finales en un orden repetitivo; cada trabajador recibe un par fijo. Iterar los resultados también expone las excepciones de los trabajadores.
Cinco trabajadores limitan las tareas activas, no las tareas activas por proxy. Si la lista tiene dos puntos finales, varias tareas pueden usar el mismo punto final a la vez. Añade una regla de capacidad separada por punto final cuando sea necesario. Para una tarea activa por URL de punto final, un arrendamiento de cola sincronizado puede reservar y devolver cada entrada.
Un reintento debe crear un intento nuevo y acotado para la misma URL. Evita las llamadas de reintento recursivas que eliminan entradas de una lista compartida: otro trabajador puede estar seleccionando de ella, y una lista agotada aún necesita un resultado explícito.