C#'ta GeeTest v3 Nasıl Çözülür

solve geetest in c# - How to Solve GeeTest v3 in C# and Post the Result Back

GeeTest, çoğu CAPTCHA kodunun üzerine kurulduğu zihinsel modeli bozar. Bir form alanına bırakılacak tek bir token yoktur. Bir çözüm şunu döndürür: üç birlikte geri gönderilmesi gereken değerler ve başladığınız challenge yaklaşık bir dakikada sona erer. Herhangi bir kısmı yanlış yapın, istek işe yarar bir hata vermeden başarısız olur.

İşte C#'ta akışın tamamı, yanlış yapması kolay olan kısımlar dahil.

İki giriş ve yalnızca biri kararlı

GeeTest v3, bir siteyi şununla tanımlar gt ve şununla tek bir deneme: challenge. Tamamen farklı davranırlar.

DeğerÖmür boyuNereden geldiği
gtSite için sabittir. Kod içine gömmek (hard-code) veya önbelleğe almak güvenlidirSitenin GeeTest init yanıtı
challengeTek kullanımlık, yaklaşık 60 saniyede sona ererAynı init yanıtı, her seferinde taze

Bu süre dolması, GeeTest başarısızlıklarının en yaygın tek nedenidir. Bir çift alır, işi kuyruğa koyar ve otuz saniye sonra başka işlerin ardında çözerseniz, challenge çoktan ölmüş olabilir. Çözmeden hemen önce alın, asla önbellekten değil.

Kurulum

# Targets .NET Standard 2.0, so Framework 4.6.1+ and .NET 6-9 all work.
dotnet add package CapSkip

CapSkip kendi makinenizde çalışır, bu yüzden önce uygulamayı başlatın ve istemciyi ayarlarındaki porta yönlendirin:

using CapSkip;

var solver = new CapSkipClient(
    apiKey: "capskip",        // any string when key validation is off
    host: "127.0.0.1",
    port: 8080,
    recaptchaTimeout: 300);   // seconds, and this one covers GeeTest too

GeeTest'in şunu kullandığını unutmayın recaptchaTimeout, değil defaultTimeout. İkincisi yalnızca görüntü CAPTCHA'ları için geçerlidir.

Onu çözmek

Bu sırayla üç konumsal argüman:

var result = await solver.GeetestAsync(
    "81388ea1fc187e0c335c0a8907ff2625",   // gt, static per site
    "7cf6a8b1a2c34d5e6f7089abcdef0123",   // challenge, fetched seconds ago
    "https://example.com/login");

Console.WriteLine(result.Challenge);
Console.WriteLine(result.Validate);
Console.WriteLine(result.Seccode);

O üç özellik cevaptır. result.Code da doldurulur, ancak GeeTest için kullanılabilir bir token yerine ham JSON dizesini tutar, bu yüzden şuna uzanmak: Code alışkanlıktan yapmak bir hatadır. Şu durumda: SolveResult, Challenge, Validate ve Seccode yalnızca GeeTest'e özgüdür ve diğer her tür için null'dır.

Bilmekte fayda var: challenge geri gelen, her zaman gönderdiğiniz değil. Girdinizi değil, dönen değeri kullanın.

Yanıtı geri gönderme

Üçünü de sitenin kendi ön yüzünün göndereceği gibi tam olarak gönderin. Çoğu GeeTest v3 entegrasyonu bu alan adlarını kullanır, ancak bir site bunları yeniden adlandırabilir; bu nedenle varsaymadan önce gerçek formu kontrol edin:

using System.Net.Http;
using System.Collections.Generic;

using var http = new HttpClient();

var form = new FormUrlEncodedContent(new[]
{
    new KeyValuePair<string, string>("geetest_challenge", result.Challenge),
    new KeyValuePair<string, string>("geetest_validate",  result.Validate),
    new KeyValuePair<string, string>("geetest_seccode",   result.Seccode),
    new KeyValuePair<string, string>("username", "..."),
    new KeyValuePair<string, string>("password", "..."),
});

var response = await http.PostAsync("https://example.com/login", form);

Üçünden ikisini göndermek ya da taze bir validate eski bir şeyle challenge, yanlış bir yanıtın reddedileceği gibi reddedilir.

Akışın tamamı, sırasıyla

İkiliyi getirmek ve çözmek yan yana olmalıdır. Bu yapı onları orada tutar:

using System;
using System.Net.Http;
using System.Text.Json;
using CapSkip;

// 1. Fetch a fresh gt/challenge pair from the site's own init endpoint.
using var http = new HttpClient();
var initJson = await http.GetStringAsync(
    "https://example.com/geetest/init?t=" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds());

using var doc = JsonDocument.Parse(initJson);
var gt        = doc.RootElement.GetProperty("gt").GetString();
var challenge = doc.RootElement.GetProperty("challenge").GetString();

// 2. Solve immediately. Do not queue this or await anything slow in between.
var result = await solver.GeetestAsync(gt, challenge, "https://example.com/login");

// 3. Post all three values together.
Console.WriteLine($"{result.Challenge} {result.Validate} {result.Seccode}");

init çağrısındaki önbellek kırıcı zaman damgası, göründüğünden daha önemlidir. GeeTest init uç noktaları aracılar tarafından sıkça önbelleğe alınır ve önbelleğe alınmış bir yanıt size zaten tüketilmiş bir challenge verir.

Başarısız olduğunda

using System;
using CapSkip;

try
{
    var result = await solver.GeetestAsync(gt, challenge, pageUrl);
}
catch (CapSkip.ValidationException) { /* missing gt or challenge */ }
catch (NetworkException)            { /* CapSkip is not running */ }
catch (ApiException)                { /* API error, often a dead challenge */ }
catch (CapSkip.TimeoutException)    { /* exceeded recaptchaTimeout */ }
catch (CapSkipError)                { /* anything else from the SDK */ }

Qualify ValidationException ve TimeoutException ile CapSkip ad alanı. Her iki ad da ayrıca şurada bulunur: System, ve her iki ad alanı da import edildiğinde niteliksiz bir catch şuna bağlanır: System türü ve sessizce hiç tetiklenmez. Temel olanı yakalamak CapSkipError sorunu tamamen ortadan kaldırır.

Uygulamada çoğu GeeTest hatası şu şekilde ortaya çıkar: ApiException ve challenge'ın çözüm bitmeden öldüğü anlamına gelir. Çözüm, aynı değerlerle yeniden denemek değil, daha sonra almaktır.

Proxy'ler ve eşzamanlılık

GeeTest, reCAPTCHA ve Turnstile'ın yanı sıra proxy kabul eden üç türden biridir. Görüntü CAPTCHA'ları kabul etmez, çünkü hedef siteye hiç dokunmazlar.

using System.Collections.Generic;

var result = await solver.GeetestAsync(gt, challenge, pageUrl,
    new Dictionary<string, object?>
    {
        ["proxy"] = new Proxy("HTTPS", "user:[email protected]:3128"),
    });

Birkaçını paralel çalıştırmak işe yarar, ancak her birinin kendi yeni alınmış çiftine ihtiyacı vardır. Önceden bir grup challenge alıp sonra bunları birlikte çözmeyin, çünkü sonuncular sıraları gelmeden süresi dolmuş olacaktır.

// Correct: fetch and solve inside the same task.
var tasks = urls.Select(async url =>
{
    var (gt, challenge) = await FetchPairAsync(url);
    return await solver.GeetestAsync(gt, challenge, url);
});

var results = await Task.WhenAll(tasks);

Sık sorulan sorular

result.Code neden kullanılabilir bir token değil?

Çünkü GeeTest'in yanıtı bir değil, üç değerdir. Code eksiksizlik için ham JSON dizesini korur, SDK ise kullanışlı kısımları şuna genişletir: Challenge, Validate ve Seccode. O üçünü kullanın.

Bir isteği tasarruf etmek için challenge'ı önbelleğe alabilir miyim?

Hayır. Tek kullanımlıktır ve yaklaşık bir dakikada sona erer. Onu önbelleğe almak, GeeTest entegrasyonlarının testte çalışıp yük altında başarısız olmasının en yaygın nedenidir, çünkü kuyruk gecikmesi çözümü sona erme penceresinin ötesine iter. gt değerini önbelleğe almak güvenlidir.

Bu, GeeTest v4 için çalışır mı?

The GeetestAsync metodu v3'ü hedefler, şunun etrafında oluşturulan kaydırma bulmacası sürümü: gt ve challenge çift. v4 parametre modelini değiştirdi, bu yüzden geçerli olanı kontrol edin API dokümantasyonu aynı çağrının çalıştığını varsaymadan önce neyin desteklendiğine bakın.

Proxy'ye ihtiyacım var mı?

Yalnızca site coğrafi konuma duyarlıysa veya adresinizi zaten şüpheli olarak değerlendiriyorsa. Bir proxy kullandığınızda aynı ağ yolundan çözüp gönderin, aksi halde uyuşmazlığın kendisi yeni bir challenge'ı tetikleyebilir.

Özet

Getir gt ve challenge çözmeden hemen önce şunu çağırın: GeetestAsync her ikisiyle ve sayfa URL'siyle, ardından gönderin Challenge, Validate ve Seccode tekrar bir araya. Doğrulamayı bozulabilir olarak değerlendirin, girdiniz yerine döndürülen doğrulamayı kullanın ve yakalayın CapSkipError ad alanı (namespace) çakışmasını önlemek için.

Diğer diller için yöntem imzaları şuradadır: GeeTest çözücü sayfası, .NET yüzeyinin tamamı şuradadır: C# CAPTCHA çözücü sayfası ve bizim üzerimizde canlı bir bulmaca deneyebilirsiniz GeeTest v3 demosu. CapSkip şunları işler: captcha atlatma yerel olarak; dolayısıyla çözüm hacmi istek başına hiçbir maliyet oluşturmaz.