각 Python ThreadPoolExecutor 작업에 URL과 프록시 할당하기
작업자들이 공유된 가변 선택 상태를 두고 경쟁하게 두지 말고, 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에 대해 새롭게 제한된 시도를 만들어야 합니다. 공유 목록에서 항목을 제거하는 재귀적 재시도 호출은 피하세요. 다른 작업자가 그 목록에서 선택 중일 수 있고, 소진된 목록에도 여전히 명시적인 결과가 필요합니다.