פתרון כמה אתגרי CAPTCHA ב-Python וב-Node.js
הגבילו את מספר תהליכי הפתרון הפעילים, ולא רק את מספר הבקשות שאתם מתחילים. הדוגמאות הבאות מריצות שמונה משימות reCAPTCHA Enterprise עצמאיות, עם ארבעה תהליכי פתרון פעילים לכל היותר בו-זמנית, ומטפלות בכל תוצאה כשהיא מתקבלת.
ארבע היא הגדרת מקביליות לדוגמה, ולא מגבלת קיבולת של solvethree. בחרו מגבלה שמתאימה למהירות שבה היישום שלכם יכול להשתמש בפתרונות שמוחזרים.
בדף הזה
הכינו את ה-SDK ואת נתוני הקלט למשימות
השתמשו ב-Python 3.10+ או ב-Node.js 22+. התקינו את ה-SDK הרשמית מכתובת ההורדה שבתיעוד; השתמשו בהורדה הישירה של החבילה. שמרו את מפתח ה-API של סביבת העבודה בשרת.
- הגדירו את
SOLVETHREE_API_KEYואתSOLVETHREE_PROXYבסביבת השרת. - החליפו את
accounts.example.comואתloginבשם המארח ובפעולה של אתר היעד שלכם. לאתר חייב כבר להיות פרופיל פעיל שזמין לסביבת העבודה שלכם; שליחת שם מארח אינה יוצרת פרופיל. - התייחסו לכל רשומה ב-
jobsכאל משימה לוגית נפרדת. הדוגמאות חוזרות על אותו אתר, אותה פעולה ואותו פרוקסי כדי לשמור על קריאות האצווה, אך מקצות לכל משימהrequestIdנפרד. - שמרו את נתוני הקלט של כל משימה ללא שינוי במהלך השחזור. תהליך פתרון עצמאי חדש דורש מזהה חדש; שחזור תהליך פתרון שנקטע דורש את המזהה המקורי ונתוני קלט זהים.
הריצו אצווה עם מקביליות מוגבלת
import os
from concurrent.futures import ThreadPoolExecutor, as_completed
from uuid import uuid4
from solvethree import Solvethree
# Each worker gets its own synchronous client.
def solve_one(job):
client = Solvethree(os.environ["SOLVETHREE_API_KEY"])
return client.solve({**job, "requestId": str(uuid4())}, timeout=180)
jobs = [
{"site": "accounts.example.com", "action": "login", "proxy": os.environ["SOLVETHREE_PROXY"]}
for _ in range(8)
]
with ThreadPoolExecutor(max_workers=4) as pool:
futures = [pool.submit(solve_one, job) for job in jobs]
for future in as_completed(futures):
try:
result = future.result()
print("Ready task:", result["id"])
# Submit this solution promptly; don't wait for the whole batch.
except Exception as error:
print("One task failed:", type(error).__name__)import { randomUUID } from 'node:crypto';
import { Solvethree } from '@solvethree/sdk';
const client = new Solvethree({ apiKey: process.env.SOLVETHREE_API_KEY });
const jobs = Array.from({ length: 8 }, () => ({
site: 'accounts.example.com', action: 'login',
proxy: process.env.SOLVETHREE_PROXY, requestId: randomUUID(),
}));
let next = 0;
async function worker() {
while (next < jobs.length) {
const job = jobs[next++];
try {
const result = await client.solve(job, { timeoutMs: 180_000 });
console.log('Ready task:', result.id);
// Submit this solution promptly, before taking another job.
} catch (error) {
console.error('One task failed:', error.constructor.name);
}
}
}
await Promise.all(Array.from({ length: Math.min(4, jobs.length) }, worker));Python זקוקה כאן לתהליכונים משום ש-`Solvethree` סינכרונית. כל קריאת solve יוצרת משימה וממתינה לתוצאה מוכנה או זורקת חריגה. אין לקוח אסינכרוני מובנה, ולכן קריאה ישירה מתוך פונקציה אסינכרונית עדיין תחסום את תהליכון לולאת האירועים של אותה פונקציה. הדוגמה משתמשת בארבעה תהליכוני עבודה במאגר תהליכונים, שלכל אחד מהם לקוח משלו, ומטפלת באובייקטי future שהושלמו בלי להמתין לכל האצווה.
Node.js מגבילה את המקביליות באמצעות ארבעה promises של תהליכי עבודה. כל תהליך עבודה ממתין לפתרון אחד לפני שהוא לוקח משימה נוספת. Promise.all ממתינה לתהליכי העבודה האלה; היא אינה מתחילה את כל המשימות בבת אחת. לעומת זאת, מיפוי ישיר של רשימת משימות בלתי מוגבלת לקריאות solve מתחיל מיד את כל הרשימה ואינו מספק מגבלת מקביליות שימושית.
שתי הדוגמאות לוכדות שגיאות לכל משימה, כך שכישלון של תהליך פתרון אחד לא עוצר את שאר המשימות. זמן ההמתנה של 180 שניות חל על כל קריאת solve, ולא על האצווה כולה.
השתמשו מיד בכל תוצאה מוכנה
החליפו את ההערה במסלול ההצלחה בשליחת הנתונים לאתר היעד שלכם לפני הרצת אצווה אמיתית. המזהה שמודפס מזהה את המשימה; הוא אינו טוקן ה-reCAPTCHA. שלחו את solution.token עם userAgent ו-secChUa שהוחזרו, באמצעות אותו פרוקסי שסופק למשימה הזאת.
אל תאספו את כל הטוקנים ואל תחכו לתהליך הפתרון האיטי ביותר לפני השימוש בהם. טפלו בכל תוצאה מוכנה בנקודה שבה היא מתקבלת. ה-SDK פותרת את ה-CAPTCHA; היא אינה שולחת את הפתרון לאתר היעד שלכם, ומשימה מוכנה אינה מוכיחה שאתר היעד קיבל את הבקשה שנשלחה לאחר מכן.
שחזרו משימה אחת שנקטעה — לא את האצווה כולה
הדוגמאות מדפיסות שמות של מחלקות שגיאה כדי לשמור על תבנית תהליכי עבודה קצרה. באינטגרציה, שמרו את המשימה שהושפעה ואת מזהי השחזור ששגיאות ה-SDK חושפות: Python משתמשת ב-request_id וב-task_id; JavaScript משתמשת ב-requestId וב-taskId.
- תהליך פתרון חורג מזמן ההמתנה או מאבד את החיבור.
בדקו אם השגיאה מכילה מזהה משימה או מזהה בקשה. ייתכן שהמשימה המרוחקת עדיין קיימת.
כדאי לנסות: חדשו את התשאול באמצעות GET כשמזהה המשימה ידוע לכם. אחרת, שחזרו את היצירה באמצעות שליחה חוזרת של נתוני קלט זהים עם אותו מזהה בקשה.
- ה-SDK זורקת TaskFailedError.
בדקו את errorCode ואת error של המשימה שהגיעה למצב סופי.
כדאי לנסות: הפסיקו לתשאל את המשימה הזאת וטפלו בגורם שדווח לפני התחלת תהליך פתרון נוסף. אל תנסו שוב באופן עיוור עם נתוני קלט לא תקינים שלא השתנו.
הרצה חוזרת של אחת מהדוגמאות מייצרת מזהי בקשה חדשים ומתחילה משימות לוגיות חדשות; זה אינו שחזור. שתי ערכות ה-SDK נמנעות מניסיון חוזר אוטומטי ליצור משימה, לכן שמרו מספיק מידע כדי לשחזר רק את המשימה שנקטעה במקום לשלוח שוב עבודה שכבר הצליחה.
מקורות ותיעוד API
הפעלת המשימה הראשונה שלך.
התחילו עם $5 בקרדיט לסביבת העבודה.