إرسال رمز CAPTCHA عبر وكيل HTTP في Go
استخدم عميل Go HTTP مستقلًا للموقع المستهدف، واضبطه بالوكيل الذي تحدده solvethree.SuccessfulProxy. أرسل Solution.Token باستخدام هوية المتصفح المُعادة. أبقِ طبقة النقل هذه الخاصة بالهدف منفصلة عن طبقة نقل API الخاصة بـ solvethree في عميل SDK.
في هذه الصفحة
إعداد المهمة
- 1.
إعداد Go SDK وبيانات الاعتماد
استخدم الوحدة الرسمية
solvethree.com/sdkبالإصدارv0.1.0مع Go 1.22 أو أحدث. تتوفر تفاصيل الإعداد في مرجع التكامل مع Go. اضبطSOLVETHREE_API_KEYعلى مفتاح API لمساحة عملك وأبقِه على الخادم. اضبطSOLVETHREE_PROXYعلى عنوان URL لوكيل HTTP أو HTTPS. - 2.
تهيئة الموقع قبل الحل
تحتاج مساحة العمل إلى ملف تعريف نشط لاسم المضيف المستهدف. أعدّ ملف تعريف الموقع أولًا؛ إرسال اسم مضيف وإجراء لا ينشئ ملفًا.
- 3.
استبدال الهدف في المثال
غيّر
accounts.example.comوالإجراءloginونقطة نهاية التطبيق بما يلائم تكاملك.Siteهو اسم مضيف، وليس عنوان URL كاملًا. في reCAPTCHA، حدّد واحدًا فقط منProxyأوProxyCandidates؛ ولا تملأ حقلَيTypeأوURLفي المهمة. النوع الافتراضي لـ reCAPTCHA هو Enterprise v3.
الإرسال عبر الوكيل الذي حل المهمة
package main
import (
"context"
"fmt"
"log"
"os"
"net/http"
"net/url"
"strings"
"time"
solvethree "solvethree.com/sdk"
)
func main() {
client, err := solvethree.NewClient(os.Getenv("SOLVETHREE_API_KEY"), nil)
if err != nil { log.Fatal(err) }
ctx, cancel := context.WithTimeout(context.Background(), 180*time.Second)
defer cancel()
input := solvethree.TaskRequest{Site: "accounts.example.com", Action: "login", Proxy: os.Getenv("SOLVETHREE_PROXY")}
result, err := client.Solve(ctx, input, solvethree.SolveOptions{})
if err != nil { log.Fatal(err) }
fmt.Println("Ready task:", result.ID)
proxy, ok := solvethree.SuccessfulProxy(input, result)
if !ok { log.Fatal("No valid successful proxy") }
proxyURL, err := url.Parse(proxy)
if err != nil { log.Fatal(err) }
transport := http.DefaultTransport.(*http.Transport).Clone()
transport.Proxy = http.ProxyURL(proxyURL)
defer transport.CloseIdleConnections()
targetClient := &http.Client{Transport: transport, Timeout: 30*time.Second,
CheckRedirect: func(*http.Request, []*http.Request) error { return http.ErrUseLastResponse }}
request, err := http.NewRequestWithContext(ctx, "POST", "https://accounts.example.com/login",
strings.NewReader(url.Values{"g-recaptcha-response": {result.Solution.Token}}.Encode()))
if err != nil { log.Fatal(err) }
request.Header.Set("User-Agent", result.Solution.UserAgent)
request.Header.Set("sec-ch-ua", result.Solution.SecChUA)
request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
response, err := targetClient.Do(request)
if err != nil { log.Fatal(err) }
defer response.Body.Close()
fmt.Println("Application HTTP status:", response.StatusCode)
// Inspect the application response to determine whether submission succeeded.
}تحل SDK المهمة لكنها لا ترسل أي شيء إلى الموقع. بعد الحل، ينسخ المثال http.DefaultTransport ويضبط Proxy في النسخة عبر http.ProxyURL. يستخدم targetClient المستقل وحده طبقة النقل تلك؛ وتبقى طبقة نقل API في عميل SDK دون تغيير.
أبقِ بيانات اعتماد الوكيل في مكوّن معلومات المستخدم ضمن عنوان URL. تحافظ url.Parse عليها لاستخدامها في طبقة نقل الوكيل. رمّز المحارف المحجوزة في اسم المستخدم أو كلمة المرور بالترميز المئوي بدلًا من تقسيم عنوان URL يدويًا أو إرسال بيانات اعتماد الوكيل ضمن ترويسة Authorization إلى الهدف.
احتفظ بمدخل المهمة الأصلي واستخدم SuccessfulProxy حتى إن كنت توفّر حاليًا وكيلًا واحدًا فقط. عند استخدام ProxyCandidates، يُحدَّد المرشح الناجح بواسطة Solution.EgressAttempts، وهو فهرس يبدأ من واحد في القائمة الأصلية. تجنّبك الدالة المساعدة تخمين المرشح الذي نجح؛ توقّف إذا أعادت false. تقبل قوائم المرشحين اثني عشر عنوان URL متميزًا لوكلاء HTTP أو HTTPS كحد أقصى، دون مسار أو استعلام أو جزء.
تضمين ترويسات الهدف وحقول النموذج والجلسة
يستخدم المثال url.Values لترميز Solution.Token بصيغة بيانات النماذج تحت الاسم g-recaptcha-response ويضبط نوع المحتوى المطابق. استبدل اسم الحقل هذا إذا كان تطبيقك يتوقع اسمًا آخر. أضف الحقول الأخرى التي تتطلبها نقطة النهاية، مثل مدخلات تسجيل الدخول وأي قيمة مضادة لـ CSRF مرتبطة بالجلسة؛ فرمز CAPTCHA ليس طلب تسجيل دخول كاملًا.
استخدم UserAgent وSecChUA المُعادين، كما يفعل المثال. إذا كان الحل يوفّر أيضًا عناصر في Headers، فطبّق تلك الترويسات المُعادة على الطلب إلى الهدف أيضًا؛ فالمثال لا ينسخ تلك المجموعة. حافظ على اتساق هوية المتصفح وصحة نوع المحتوى بالنسبة إلى متن الطلب الذي ترسله.
لا يحتوي المثال على مخزن لملفات تعريف الارتباط. إذا كان الهدف يتطلب جلسة، فأنشئ مخزنًا باستخدام net/http/cookiejar، وأرفقه بـ targetClient.Jar قبل بدء تدفق التعامل مع الهدف، وأعِد استخدام ذلك العميل لطلب الصفحة وإرسال النموذج. استخدم الوكيل الناجح نفسه طوال تلك الجلسة. عميل API الخاص بـ solvethree ليس عميل جلسة الهدف.
تحقق من خطأ الحل قبل الوصول إلى الحل. وحدها المهمة الجاهزة تتضمن حلاً صالحًا للاستخدام؛ ويوضح errorCode وerror في المهمة الفاشلة سبب فشلها. بالنسبة إلى الطلب الموجّه إلى الهدف، عالج الخطأ الناتج عن Do، ثم تحقق من حالة HTTP قبل تفسير نص الاستجابة. أغلق response.Body كلما أعاد Do استجابة دون خطأ، بما في ذلك استجابات HTTP غير الناجحة.
يعطّل المثال عمليات إعادة التوجيه التلقائية ويطبع حالة التطبيق. افحص نص الاستجابة وأي إعادة توجيه متوقعة لتحديد ما إذا كان التطبيق قد قبل الإرسال. جاهزية المهمة، أو حتى نجاح حالة HTTP وحده، لا تثبت هذه النتيجة.
المصادر ومرجع API
شغّل مهمتك الأولى.
ابدأ برصيد قدره $5 في مساحة العمل.