Asignar un URL e un proxy a cada tarefa de Python ThreadPoolExecutor
Asigna un proxy antes de enviar unha tarefa de solicitude de Python en lugar de deixar que os traballadores compitan por un estado de selección compartido e mutable.
O map dun pool pasa un elemento ao traballador á vez. Fai dese elemento unha tarefa completa, incluído o URL e o proxy seleccionado, para que o traballador non deduza a súa ruta dunha lista global cambiante.
Para un número finito de urls, fornece unha lista non baleira de URL de proxy validadas. Os candidatos HTTP públicos están dispoñibles na 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 e handle_result fornéceos a aplicación. O coordinador asigna os puntos finais nunha orde repetitiva; cada traballador recibe un par fixo. Iterar os resultados tamén expón as excepcións dos traballadores.
Cinco traballadores limitan as tarefas activas, non as tarefas activas por proxy. Se a lista ten dous puntos finais, varias tarefas poden usar o mesmo punto final á vez. Engade unha regra de capacidade separada por punto final cando sexa necesario. Para unha tarefa activa por URL de punto final, un arrendamento de cola sincronizado pode reservar e devolver cada entrada.
Un reintento debe crear un novo intento limitado para o mesmo URL. Evita as chamadas de reintento recursivas que eliminan entradas dunha lista compartida: outro traballador pode estar seleccionando dela, e unha lista esgotada aínda necesita un resultado explícito.