Задаване на URL и прокси за всяка задача на Python ThreadPoolExecutor
Задайте прокси, преди да изпратите задача за заявка на Python, вместо да оставяте работниците да се състезават за споделено променливо състояние на избор.
map на пула предава по един елемент на работника. Направете този елемент пълна задача, включително URL и избрания прокси, така че работникът да не извежда маршрута си от променлив глобален списък.
За краен брой urls предоставете непразен списък с валидирани URL на прокси. Публичните HTTP кандидати са налични в списъка с 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 и handle_result се предоставят от приложението. Координаторът задава крайни точки в повтарящ се ред; всеки работник получава една фиксирана двойка. Итерирането на резултатите също показва изключенията на работниците.
Пет работника ограничават активните задачи, а не активните задачи на прокси. Ако списъкът има две крайни точки, няколко задачи могат да използват една и съща крайна точка едновременно. Добавете отделно правило за капацитет на крайна точка, когато е необходимо. За една активна задача на URL на крайна точка, синхронизиран наем на опашка може да резервира и връща всеки запис.
Повторният опит трябва да създава нов ограничен опит за същия URL. Избягвайте рекурсивни извиквания за повторен опит, които премахват записи от споделен списък: друг работник може да избира от него, а изчерпан списък все още се нуждае от ясен резултат.