Atribuir um URL e um proxy a cada tarefa Python ThreadPoolExecutor
Atribua um proxy antes de enviar uma tarefa de solicitação Python em vez de deixar os workers competirem por um estado de seleção compartilhado e mutável.
O map de um pool passa um item ao worker de cada vez. Torne esse item uma tarefa completa, incluindo o URL e o proxy selecionado, para que o worker não deduza a sua rota de uma lista global em mudança.
Para urls finitos, forneça uma lista não vazia de URL de proxy validadas. Candidatos HTTP públicos estão disponíveis 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 são fornecidos pela aplicação. O coordenador atribui os pontos finais numa ordem repetida; cada worker recebe um par fixo. Iterar os resultados também revela exceções dos workers.
Cinco workers limitam as tarefas ativas, não as tarefas ativas por proxy. Se a lista tiver dois pontos finais, várias tarefas podem usar o mesmo ponto final ao mesmo tempo. Acrescente uma regra de capacidade separada por ponto final quando necessário. Para uma tarefa ativa por URL de ponto final, um arrendamento de fila sincronizado pode reservar e devolver cada entrada.
Uma nova tentativa deve criar uma nova tentativa limitada para o mesmo URL. Evite chamadas de nova tentativa recursivas que removem entradas de uma lista compartilhada: outro worker pode estar a selecionar dela, e uma lista esgotada ainda precisa de um resultado explícito.