حل reCAPTCHA Enterprise باستخدام Node.js
استخدم حزمة SDK الرسمية لـ JavaScript من solvethree على Node.js 22+. اضبط ملف تعريف نشطًا للموقع، وقدّم اسم مضيف الموقع والإجراء، ونفّذ الحل عبر وكيل. تعيد حزمة SDK الرمز وهوية المتصفح؛ ويتولى تطبيقك إرسالهما إلى الجهة المستهدفة.
في هذه الصفحة
تثبيت حزمة SDK وضبط الموقع
ثبّت الحزمة الرسمية مباشرةً من solvethree.com:
npm install https://solvethree.com/downloads/solvethree-sdk-0.1.0.tgz- 1.
تفعيل ملف تعريف الموقع
أعدّ الموقع المستهدف في لوحة التحكم، وتأكد من أن ملف تعريفه نشط ومتاح لمساحة عملك. إرسال اسم مضيف وإجراء لا ينشئ ملف تعريف. راجع إعداد ملف تعريف الموقع.
- 2.
ضبط بيئة الخادم
عيّن SOLVETHREE_API_KEY إلى مفتاح API لمساحة عملك وSOLVETHREE_PROXY إلى عنوان URL للوكيل في بيئة عملية Node.js. احتفظ بمفتاح API على الخادم؛ ولا تكشفه في كود المتصفح.
- 3.
تحضير السكربت
احفظ المثال التالي باسم solve.mjs. استبدل accounts.example.com باسم المضيف الذي أعددته، واستبدل login بإجراء reCAPTCHA الفعلي للصفحة.
طلب رمز Enterprise
استخدم اسم مضيف للحقل site، وليس عنوان URL لصفحة. يستخدم reCAPTCHA القيمة enterprise-v3 افتراضيًا، لذا لا يحتاج المثال إلى recaptchaType. لا تضف type أو url. يتطلب الطلب واحدًا فقط من proxy أو proxyCandidates؛ ويستخدم هذا المثال وكيلًا واحدًا.
import { randomUUID } from 'node:crypto';
import { Solvethree, SolvethreeError, TaskFailedError } from '@solvethree/sdk';
const client = new Solvethree({ apiKey: process.env.SOLVETHREE_API_KEY });
const request = {
site: 'accounts.example.com', // Use your configured hostname.
action: 'login', // Use the page's actual action.
proxy: process.env.SOLVETHREE_PROXY,
requestId: randomUUID(),
};
let result;
try {
result = await client.solve(request, { timeoutMs: 180_000 });
} catch (error) {
if (error instanceof TaskFailedError) {
throw new Error(`Task failed: ${error.errorCode}`);
}
if (error instanceof SolvethreeError) {
// Save these IDs; use them to recover the existing task.
console.error({ requestId: error.requestId, taskId: error.taskId });
}
throw error;
}
const { token, userAgent, secChUa } = result.solution;
console.log('Ready task:', result.id); // Keep solution credentials private.شغّل السكربت باستخدام Node.js بعد تعيين متغيرات البيئة. ينشئ solve المهمة مرة واحدة ويستعلم دوريًا حتى تصبح جاهزة أو يطرح استثناءً. تحدّ المهلة البالغة 180,000 مللي ثانية من مدة انتظار العميل.
لكل حقل من الحقول المُعادة وظيفة مختلفة:
- يحدّد
result.idالمهمة. وهو ليس رمز CAPTCHA. result.solution.tokenهو القيمة التي يجب إرسالها في حقل CAPTCHA الخاص بالتطبيق.- يمثّل
result.solution.userAgentوresult.solution.secChUaهوية المتصفح التي يجب استخدامها مع ذلك الرمز.
حافظ على سرية قيم الحل. إذا كنت بحاجة إلى الاستئناف بعد إعادة تشغيل العملية، فاحفظ requestId ومدخلات المهمة كما هي تمامًا قبل استدعاء solve، مع حماية أي بيانات اعتماد للوكيل.
الإرسال عبر الوكيل نفسه
تابع في السكربت نفسه بعد أن يعيد solve النتيجة. يستخدم هذا المثال undici، التي يجب تثبيتها بشكل منفصل كما يوضح التعليق فيه. يرسل الرمز عبر request.proxy ويستخدم كلا حقلَي هوية المتصفح المُعادين.
// Continue after client.solve(). Install undici separately: npm install undici@7.
import { fetch, ProxyAgent } from 'undici';
const dispatcher = new ProxyAgent(request.proxy);
try {
// Replace the URL and form fields with your application's contract.
const response = await fetch('https://accounts.example.com/login', {
method: 'POST',
dispatcher,
redirect: 'manual',
headers: {
'user-agent': result.solution.userAgent,
'sec-ch-ua': result.solution.secChUa,
},
body: new URLSearchParams({
'g-recaptcha-response': result.solution.token,
}),
signal: AbortSignal.timeout(30_000),
});
console.log('Application HTTP status:', response.status);
await response.arrayBuffer();
} finally {
await dispatcher.close();
}استبدل عنوان URL وحقول النموذج بما تتطلبه واجهة تطبيقك. يقدّم المثال g-recaptcha-response فقط؛ أدرج أي حقول أخرى وبيانات جلسة يتطلبها التطبيق. حافظ على تطابق الجهة المستهدفة مع الموقع والإجراء اللذين نفّذت الحل لهما.
نظرًا إلى أن طلب الحل يستخدم وكيلًا واحدًا، فإن إعادة استخدام request.proxy تُبقي الإرسال عبر ذلك الوكيل. إذا غيّرت الطلب لاستخدام proxyCandidates، فاختر الوكيل الذي نجح باستخدام الدالة المساعدة successfulProxy في حزمة SDK بدلًا من ذلك.
تعني المهمة الجاهزة أن حلًا قد أُنشئ، وليس أن الجهة المستهدفة قبلت طلب تطبيقك. افحص استجابة الجهة المستهدفة للتحقق من شرط النجاح الفعلي لديها؛ فطباعة رمز حالة HTTP لا تكفي. لتشخيص الرفض، راجع رفض رمز جاهز.
معالجة الإخفاقات واستئناف الطلبات المنقطعة
يميّز مثال الحل بين إخفاقات المهام النهائية وأخطاء SDK الأخرى. حافظ على هذا التمييز: فالمهمة الفاشلة وطلب HTTP الفاشل يحتاجان إلى معالجة مختلفة.
- يطرح solve الاستثناء TaskFailedError
يتضمن الاستثناء errorCode وtaskId. استدعِ getTask(taskId) إذا كنت بحاجة إلى الاستجابة الكاملة للمهمة الفاشلة، بما في ذلك نص الخطأ.
جرّب هذا: أوقف الاستعلام الدوري عن تلك المهمة وعالج السبب المُبلّغ عنه قبل إنشاء أخرى. لا تُعد المحاولة بمدخلات غير صالحة لم تتغير.
- يتضمن SolvethreeError الحقل taskId
لدى حزمة SDK معرّف للمهمة الموجودة.
جرّب هذا: استأنف الاستعلام الدوري باستخدام getTask. تابع عندما تكون الحالة pending أو solving، ولا تستخدم الحل إلا عندما تصبح ready، وتوقف عند failed.
- انقطع الإنشاء ولا يتوفر سوى requestId
انتهاء مهلة الاتصال لا يثبت أن المهمة لم تُنشأ.
جرّب هذا: استعد المهمة باستخدام createTask مع مدخلات المهمة المطابقة وrequestId نفسه. تؤدي إعادة استخدام ذلك المعرّف مع مدخلات مختلفة إلى تعارض.
- ترفض واجهة API طلب HTTP
افحص رمز حالة HTTP الذي يتيحه ApiError بدلًا من التعامل مع الاستجابة على أنها مهمة جاهزة أو فاشلة.
جرّب هذا: عالج خطأ HTTP قبل معالجة بيانات استجابة النجاح. لا تفترض أن كل إخفاق سببه عدم كفاية الرصيد.
يُنشئ المثال requestId جديدًا في كل مرة يبدأ فيها البرنامج. إعادة تشغيله دون تعديل ليست استئنافًا: استخدم الطلب والمعرّفات التي حفظتها بدلًا من ذلك. لا تعيد حزمة SDK محاولة إنشاء المهمة تلقائيًا أبدًا؛ لكنها تلتزم بـ Retry-After عند حدوث إخفاقات مؤقتة في الاستعلام الدوري ضمن المهلة النهائية للحل.
للاطلاع على إعدادات الاستعلام الدوري والانتظار الصريحة، راجع الاستعلام الدوري عن المهام والمهل الزمنية.
المصادر ومرجع API
شغّل مهمتك الأولى.
ابدأ برصيد قدره $5 في مساحة العمل.