הקצאת 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. הימנעו מקריאות ניסיון חוזר רקורסיביות שמסירות רשומות מרשימה משותפת: עובד אחר עשוי לבחור ממנה, ורשימה שמוצתה עדיין זקוקה לתוצאה מפורשת.