Go'da CAPTCHA görevlerini eşzamanlı çözün
Tek bir paylaşılan Go SDK istemcisi ve sabit bir işçi havuzu kullanın. Her işe kendi bağlamını verin; ardından token'ları sonraki bir toplu işlem için biriktirmek yerine hazır olan her çözümü hemen gönderin.
Bu sayfada
İstemciyi ve hedefi hazırlayın
- Go 1.22 veya üzerini ve resmi
solvethree.com/sdkmodülününv0.1.0sürümünü kullanın. Kurulum ayrıntıları Go entegrasyon belgelerinde yer alır. - Sunucu ortamında
SOLVETHREE_API_KEYveSOLVETHREE_PROXYdeğişkenlerini ayarlayın. API anahtarını tarayıcı koduna dahil etmeyin. accounts.example.comvelogindeğerlerini hedef ana makine adınız ve eyleminizle değiştirin. Çalışma alanında bu site için etkin bir profil bulunmalıdır; ana makine adını göndermek profil oluşturmaz. Site profili kurulumuna bakın.
Örnek, varsayılan olan reCAPTCHA Enterprise'ı talep eder. Tek bir proxy sağlar ve Type ile URL alanlarını bilerek ayarlamaz: reCAPTCHA istekleri bu alanları değil, sitenin ana makine adını ve eylemi kullanır.
İstemci sayısını değil, iş yükünü sınırlayın
İstemci eşzamanlı kullanım için güvenlidir. Bu örnek dört işçi başlatır ve tamponlanmamış bir kanal üzerinden onlara sekiz iş iletir. Üretici, her iş için bir goroutine başlatmak yerine tüm işçiler meşgulken bekler. Dört, örnek bir uygulama ayarıdır; solvethree hizmet sınırı değildir.
package main
import (
"context"
"fmt"
"log"
"os"
"sync"
"time"
solvethree "solvethree.com/sdk"
)
func main() {
client, err := solvethree.NewClient(os.Getenv("SOLVETHREE_API_KEY"), nil)
if err != nil { log.Fatal(err) }
jobs := make(chan int)
var workers sync.WaitGroup
for worker := 0; worker < 4; worker++ {
workers.Add(1)
go func() {
defer workers.Done()
for job := range jobs {
ctx, cancel := context.WithTimeout(context.Background(), 180*time.Second)
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 { cancel(); log.Printf("Job %d: %v", job, err); continue }
fmt.Println("Ready task:", result.ID)
// Submit this solution now, with its proxy and browser identity.
cancel()
}
}()
}
for job := 0; job < 8; job++ { jobs <- job }
close(jobs)
workers.Wait()
}Her işçi, her iş için ayrı bir 180 saniyelik bağlam oluşturur. Solve, görevi bir kez oluşturur ve sonucunu bekler. Örnekte RequestID belirtilmediğinden SDK, bu oluşturma işlemi için bir kimlik üretir. Başarısız çağrı günlüğe kaydedilir ve continue yalnızca ilgili işçiyi bir sonraki işine geçirir; toplu işlemi durdurmaz.
Her işin bağlam kaynaklarını gecikmeden serbest bırakması için iptal işlemini gösterildiği gibi döngünün içinde tutun. İptal, yerel beklemeyi durdurur; uzaktaki işi iptal etmez.
Başka bir iş almadan önce çözümü işleyin
Örnek, hazır görevin kimliğini yazdırır; hedefe hiçbir şey göndermez. Yorumun yerine hedef isteğinizi ekleyin, ardından işçi başka bir iş almadan önce bu işin gönderim sonucunu raporlayın. Token'ları workers.Wait sonrasında kullanmak üzere bir dilime eklemeyin.
result.IDdeğil,result.Solution.Tokengönderin.- Başarılı proxy'yi belirlemek için özgün görev ve hazır sonuçla birlikte
SuccessfulProxykullanın. DöndürülenUserAgentveSecChUAtarayıcı kimliğiyle bu proxy üzerinden gönderim yapın. - Gönderimi işin bağlamı içinde,
cancel()çağrısından önce yapın. Böylece 180 saniyelik son süre hem çözümü hem de gönderimi kapsar; ayrı bir süre bütçesine ihtiyacınız varsa ayrı bir gönderim bağlamı kullanın.
Çözüm ve hedefe gönderim sonuçlarını ayrı ayrı raporlayın. Hazır bir görev kullanılabilir bir çözüm sağlar, ancak uygulama isteğini kabul edip etmediğini yalnızca hedefin yanıtı gösterir.
Toplu işlemi yeniden başlatmadan kesintiye uğrayan bir işi kurtarın
Bu küçük örnek için hatayı günlüğe kaydetmek yeterlidir, ancak kurtarma desteği olan bir entegrasyon her işin görev girdilerini eksiksiz olarak ve mevcut istek ve görev kimliklerini saklamalıdır. Zaman aşımı, görev oluşturmanın başarısız olduğunu kanıtlamaz.
RequestIDveTaskIDdeğerlerini almak için*solvethree.Errortürünü çıkarın. Görev kimliği biliniyorsa yeni bir bağlam altındaGetTaskile sonucu almayı sürdürün.- Oluşturma işleminin sonucu belirsizse ve istek kimliği elinizdeyse özgün girdileri aynı
RequestIDile yeniden gönderin. Aynı istek mevcut görevi döndürür; kimliği yeniden kullanırken girdileri değiştirmek çakışmaya yol açar. *TaskFailedErroriçinErrorCodedeğerini kaydedin veErrormetnine ihtiyacınız varsa başarısız görevi alın. Bu görevi sorgulamayı bırakın ve aynı geçersiz girdileri körü körüne yeniden göndermek yerine sorunun nedenini giderin.
HTTP hatalarını görevin nihai başarısızlığından ayrı tutun. errors.As, StatusCode ve RetryAfter içeren iç içe bir *APIError çıkarabilir. Solve, HTTP 429, 502, 503 veya 504 içeren geçici sorgulama yanıtlarını zaten yeniden dener ve bağlamın son süresi içinde Retry-After değerine uyar. Görev oluşturma hiçbir zaman otomatik olarak yeniden denenmez.
Kaynaklar ve API referansı
İlk görevinizi çalıştırın.
$5 çalışma alanı kredisiyle başlayın.