تحلّ CaptchaAI أي اختبار CAPTCHA داخل PowerShell عبر الأمر المدمج Invoke-RestMethod وحده — دون تثبيت أي وحدة خارجية أو مكتبة إضافية. تتلخّص الآلية في أربع خطوات متكررة:
- أرسل المهمة إلى نقطة النهاية
in.phpواحصل على معرّفها. - استطلع
res.phpدوريًا حتى تجهز الاستجابة. - استلم التوكن المحلول.
- مرّره إلى النموذج أو إلى الطلب التالي في سير العمل.
يشرح هذا الدليل كيفية تطبيق تلك الخطوات على reCAPTCHA v2/v3 وCloudflare Turnstile واختبارات CAPTCHA الصورية، عبر دوال ووحدة PowerShell جاهزة للإنتاج يمكنك إسقاطها مباشرة في مهام Windows المجدولة أو سكربتات الإدارة لديك.
لماذا تختار PowerShell لحل الكابتشا؟
PowerShell هو المسار الأقصر لأي فريق يعمل على Windows بالفعل، لأنه يوفّر كل ما تحتاجه للتكامل مع واجهة CaptchaAI دون أدوات وسيطة:
- مدمج في Windows — لا حاجة لأي تثبيت (PowerShell 5.1 فما فوق)
Invoke-RestMethod— دعم أصلي لواجهات REST مع تحليل JSON تلقائيًا- Task Scheduler — جدولة السكربتات المعتمدة على حل الكابتشا محليًا
- مناسب لخطوط الأتمتة — تربط الحل مباشرةً بالخطوة التالية في سير العمل
- متعدد المنصات — يعمل PowerShell 7+ على Linux وmacOS أيضًا
تخيّل فريق ضمان جودة في متجر تجارة إلكترونية بالخليج يشغّل اختبارات انحدار ليلية على خوادم Windows داخلية: كل عملية تسجيل دخول أو تسجيل حساب تعبر بوابة reCAPTCHA أو Turnstile. بدلاً من إيقاف الاختبار عند هذه النقطة، يستدعي السكربت CaptchaAI ويكمل التدفق آليًا — وهذا هو بالضبط ما تبنيه في الأقسام التالية.
ما تحتاجه قبل البدء
- PowerShell 5.1 (على Windows) أو PowerShell 7+ (عبر المنصات المختلفة)
- مفتاح CaptchaAI API (أنشئ حسابك واحصل عليه من هنا)
- لا وحدات إضافية مطلوبة — الأوامر المدمجة تكفي
الدالتان الأساسيتان: الإرسال والاستطلاع
تقوم كل عملية حل على لبنتين قابلتين لإعادة الاستخدام:
Submit-CaptchaTask— تبني حمولة الطلب وتعيد معرّف المهمة.Get-CaptchaResult— تستطلع النتيجة حتى تجهز أو تنتهي المهلة.
بمجرد بنائهما، يصبح حل أي نوع من الكابتشا مجرد تمرير الوسائط الصحيحة.
دالة إرسال المهمة
تبني هذه الدالة حمولة الطلب وترسلها إلى in.php، ثم تتحقق من نجاح الإرسال قبل إعادة معرّف المهمة:
function Submit-CaptchaTask {
param(
[Parameter(Mandatory)]
[string]$ApiKey,
[Parameter(Mandatory)]
[hashtable]$TaskParams
)
$body = @{
key = $ApiKey
json = 1
} + $TaskParams
$response = Invoke-RestMethod -Uri "https://ocr.captchaai.com/in.php" `
-Method Post `
-Body $body `
-ContentType "application/x-www-form-urlencoded"
if ($response.status -ne 1) {
throw "Submit failed: $($response.request)"
}
return $response.request
}
دالة استطلاع النتيجة
بعد الإرسال، تستفسر هذه الدالة عن النتيجة من res.php على فترات منتظمة. إذا كان الرد CAPCHA_NOT_READY فإنها تنتظر وتعيد المحاولة حتى تجهز الاستجابة أو تنتهي المهلة المحددة:
function Get-CaptchaResult {
param(
[Parameter(Mandatory)]
[string]$ApiKey,
[Parameter(Mandatory)]
[string]$TaskId,
[int]$MaxWaitSeconds = 300,
[int]$PollIntervalSeconds = 5
)
$deadline = (Get-Date).AddSeconds($MaxWaitSeconds)
while ((Get-Date) -lt $deadline) {
Start-Sleep -Seconds $PollIntervalSeconds
$response = Invoke-RestMethod -Uri "https://ocr.captchaai.com/res.php" `
-Method Get `
-Body @{
key = $ApiKey
action = "get"
id = $TaskId
json = 1
}
if ($response.request -eq "CAPCHA_NOT_READY") {
Write-Verbose "Waiting for solution..."
continue
}
if ($response.status -ne 1) {
throw "Solve failed: $($response.request)"
}
return $response.request
}
throw "Timeout: CAPTCHA not solved within $MaxWaitSeconds seconds"
}
حل الأنواع الشائعة من الكابتشا في PowerShell
الأقسام الأربعة التالية تشترك في الدالتين السابقتين؛ يتغيّر فقط ما تمرّره في TaskParams بحسب نوع الكابتشا.
reCAPTCHA v2
النوع الأكثر شيوعًا في نماذج تسجيل الدخول والتسجيل. تحتاج فقط إلى عنوان الصفحة ومفتاح الموقع (sitekey)، ثم تستدعي الدالتين السابقتين لتحصل على التوكن الجاهز للإرسال:
function Solve-RecaptchaV2 {
param(
[Parameter(Mandatory)]
[string]$ApiKey,
[Parameter(Mandatory)]
[string]$SiteUrl,
[Parameter(Mandatory)]
[string]$SiteKey
)
Write-Host "Submitting reCAPTCHA v2 task..."
$taskId = Submit-CaptchaTask -ApiKey $ApiKey -TaskParams @{
method = "userrecaptcha"
googlekey = $SiteKey
pageurl = $SiteUrl
}
Write-Host "Task ID: $taskId"
Write-Host "Polling for solution..."
$token = Get-CaptchaResult -ApiKey $ApiKey -TaskId $taskId
Write-Host "Solved! Token: $($token.Substring(0, [Math]::Min(50, $token.Length)))..."
return $token
}
# Usage
$apiKey = "YOUR_API_KEY"
$token = Solve-RecaptchaV2 `
-ApiKey $apiKey `
-SiteUrl "https://example.com/login" `
-SiteKey "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"
Cloudflare Turnstile
يتطابق تدفق Turnstile مع reCAPTCHA تقريبًا؛ الفارق الوحيد هو قيمة method واسم حقل مفتاح الموقع. تحلّ CaptchaAI اختبارات Turnstile بسرعة، ما يجعلها مناسبة للتدفقات الحسّاسة للزمن:
function Solve-Turnstile {
param(
[Parameter(Mandatory)]
[string]$ApiKey,
[Parameter(Mandatory)]
[string]$SiteUrl,
[Parameter(Mandatory)]
[string]$SiteKey
)
$taskId = Submit-CaptchaTask -ApiKey $ApiKey -TaskParams @{
method = "turnstile"
key = $SiteKey
pageurl = $SiteUrl
}
return Get-CaptchaResult -ApiKey $ApiKey -TaskId $taskId
}
# Usage
$token = Solve-Turnstile `
-ApiKey "YOUR_API_KEY" `
-SiteUrl "https://example.com/form" `
-SiteKey "0x4AAAAAAAB5..."
reCAPTCHA v3 مع تحديد الإجراء
يعتمد الإصدار الثالث على درجة سلوكية بدلاً من نقرة، لذا تضيف الوسيطين version وaction. اجعل قيمة action مطابقة لتلك المعرّفة في الصفحة المستهدفة (مثل login أو verify) للحصول على أفضل درجة:
function Solve-RecaptchaV3 {
param(
[Parameter(Mandatory)]
[string]$ApiKey,
[Parameter(Mandatory)]
[string]$SiteUrl,
[Parameter(Mandatory)]
[string]$SiteKey,
[string]$Action = "verify",
)
$taskId = Submit-CaptchaTask -ApiKey $ApiKey -TaskParams @{
method = "userrecaptcha"
googlekey = $SiteKey
pageurl = $SiteUrl
version = "v3"
action = $Action
}
return Get-CaptchaResult -ApiKey $ApiKey -TaskId $taskId
}
اختبارات CAPTCHA الصورية (OCR)
بالنسبة للصور النصية، تُرمّز الملف بصيغة Base64 وترسله بالطريقة base64. هذا مفيد للنماذج القديمة أو لوحات الإدارة الداخلية التي ما زالت تعرض كابتشا صوريًا بسيطًا:
function Solve-ImageCaptcha {
param(
[Parameter(Mandatory)]
[string]$ApiKey,
[Parameter(Mandatory)]
[string]$ImagePath
)
if (-not (Test-Path $ImagePath)) {
throw "Image file not found: $ImagePath"
}
$imageBytes = [System.IO.File]::ReadAllBytes($ImagePath)
$base64 = [Convert]::ToBase64String($imageBytes)
$taskId = Submit-CaptchaTask -ApiKey $ApiKey -TaskParams @{
method = "base64"
body = $base64
}
return Get-CaptchaResult -ApiKey $ApiKey -TaskId $taskId
}
# Usage
$text = Solve-ImageCaptcha -ApiKey "YOUR_API_KEY" -ImagePath "C:\captcha.png"
Write-Host "CAPTCHA text: $text"
حل صورة من رابط مباشر
إن كانت الصورة معروضة على الويب، فلا داعي لحفظها محليًا؛ نزّلها إلى الذاكرة عبر Invoke-WebRequest ثم رمّزها مباشرة:
function Solve-ImageCaptchaFromUrl {
param(
[Parameter(Mandatory)]
[string]$ApiKey,
[Parameter(Mandatory)]
[string]$ImageUrl
)
$imageBytes = (Invoke-WebRequest -Uri $ImageUrl).Content
$base64 = [Convert]::ToBase64String($imageBytes)
$taskId = Submit-CaptchaTask -ApiKey $ApiKey -TaskParams @{
method = "base64"
body = $base64
}
return Get-CaptchaResult -ApiKey $ApiKey -TaskId $taskId
}
بناء وحدة حل متكاملة (Module)
بدلاً من نثر الدوال عبر ملفاتك، اجمعها في صنف (class) واحد قابل لإعادة الاستخدام. احفظ الملف باسم CaptchaAI.psm1 لتستورده في أي سكربت لاحقًا، وأضف طريقة GetBalance لمتابعة الرصيد قبل تشغيل الدفعات الكبيرة:
class CaptchaAISolver {
[string]$ApiKey
[string]$BaseUrl = "https://ocr.captchaai.com"
[int]$PollInterval = 5
[int]$MaxWait = 300
CaptchaAISolver([string]$apiKey) {
$this.ApiKey = $apiKey
}
[string] SolveRecaptchaV2([string]$siteUrl, [string]$siteKey) {
return $this.Solve(@{
method = "userrecaptcha"
googlekey = $siteKey
pageurl = $siteUrl
})
}
[string] SolveTurnstile([string]$siteUrl, [string]$siteKey) {
return $this.Solve(@{
method = "turnstile"
key = $siteKey
pageurl = $siteUrl
})
}
[string] SolveImage([string]$imagePath) {
$bytes = [System.IO.File]::ReadAllBytes($imagePath)
$base64 = [Convert]::ToBase64String($bytes)
return $this.Solve(@{
method = "base64"
body = $base64
})
}
[double] GetBalance() {
$response = Invoke-RestMethod -Uri "$($this.BaseUrl)/res.php" `
-Body @{ key = $this.ApiKey; action = "getbalance"; json = 1 }
return [double]$response.request
}
hidden [string] Solve([hashtable]$params) {
$taskId = $this.Submit($params)
return $this.Poll($taskId)
}
hidden [string] Submit([hashtable]$params) {
$body = @{ key = $this.ApiKey; json = 1 } + $params
$response = Invoke-RestMethod -Uri "$($this.BaseUrl)/in.php" `
-Method Post -Body $body
if ($response.status -ne 1) { throw "Submit: $($response.request)" }
return $response.request
}
hidden [string] Poll([string]$taskId) {
$deadline = (Get-Date).AddSeconds($this.MaxWait)
while ((Get-Date) -lt $deadline) {
Start-Sleep -Seconds $this.PollInterval
$response = Invoke-RestMethod -Uri "$($this.BaseUrl)/res.php" `
-Body @{ key = $this.ApiKey; action = "get"; id = $taskId; json = 1 }
if ($response.request -eq "CAPCHA_NOT_READY") { continue }
if ($response.status -ne 1) { throw "Solve: $($response.request)" }
return $response.request
}
throw "Timeout"
}
}
# Export
Export-ModuleMember
استدعاء الوحدة
بعد الاستيراد، تُنشئ نسخة واحدة من الصنف وتستدعي طرقه مباشرة:
using module .\CaptchaAI.psm1
$solver = [CaptchaAISolver]::new("YOUR_API_KEY")
# Check balance
$balance = $solver.GetBalance()
Write-Host "Balance: `$$balance"
# Solve reCAPTCHA v2
$token = $solver.SolveRecaptchaV2("https://example.com/login", "SITEKEY")
Write-Host "Token: $($token.Substring(0, 50))..."
من الحل إلى التشغيل في الإنتاج
بعد أن أصبح لديك توكن محلول، تبقى أربع لبنات عملية تحوّل السكربت إلى أتمتة موثوقة: إرسال النموذج، التوازي، إعادة المحاولة، ثم الجدولة.
إرسال النموذج بعد الحصول على التوكن
حل الكابتشا نصف المهمة؛ الخطوة المكمّلة هي إدراج التوكن في حمولة النموذج تحت الحقل g-recaptcha-response ثم إرسال الطلب:
function Submit-FormWithToken {
param(
[string]$Url,
[string]$Token,
[hashtable]$FormData
)
$body = $FormData + @{
"g-recaptcha-response" = $Token
}
$response = Invoke-WebRequest -Uri $Url `
-Method Post `
-Body $body `
-ContentType "application/x-www-form-urlencoded"
return $response
}
# Usage
$token = Solve-RecaptchaV2 -ApiKey "YOUR_API_KEY" `
-SiteUrl "https://example.com/login" `
-SiteKey "SITEKEY"
$result = Submit-FormWithToken `
-Url "https://example.com/login" `
-Token $token `
-FormData @{
username = "user@example.com"
password = "password"
}
Write-Host "Response: $($result.StatusCode)"
الحل المتوازي عبر Start-Job
عندما تحتاج لمعالجة عدة مواقع في آنٍ واحد، شغّل كل مهمة داخل وظيفة مستقلة عبر Start-Job واجمع النتائج بعد اكتمالها. لاحظ أن التوازي الفعلي مقيّد بعدد الـ threads المتاح في خطتك:
$apiKey = "YOUR_API_KEY"
$tasks = @(
@{ Url = "https://site-a.com"; Key = "SITEKEY_A" },
@{ Url = "https://site-b.com"; Key = "SITEKEY_B" },
@{ Url = "https://site-c.com"; Key = "SITEKEY_C" }
)
$jobs = $tasks | ForEach-Object {
$task = $_
Start-Job -ScriptBlock {
param($ApiKey, $Url, $SiteKey)
$taskId = (Invoke-RestMethod -Uri "https://ocr.captchaai.com/in.php" -Method Post -Body @{
key = $ApiKey; json = 1; method = "userrecaptcha"
googlekey = $SiteKey; pageurl = $Url
}).request
$deadline = (Get-Date).AddSeconds(300)
while ((Get-Date) -lt $deadline) {
Start-Sleep -Seconds 5
$result = Invoke-RestMethod -Uri "https://ocr.captchaai.com/res.php" -Body @{
key = $ApiKey; action = "get"; id = $taskId; json = 1
}
if ($result.request -ne "CAPCHA_NOT_READY" -and $result.status -eq 1) {
return @{ Url = $Url; Token = $result.request }
}
}
return @{ Url = $Url; Error = "Timeout" }
} -ArgumentList $apiKey, $task.Url, $task.Key
}
# Wait and collect results
$results = $jobs | Wait-Job | Receive-Job
$results | ForEach-Object {
if ($_.Token) {
Write-Host "$($_.Url): $($_.Token.Substring(0, 50))..."
} else {
Write-Host "$($_.Url): $($_.Error)" -ForegroundColor Red
}
}
$jobs | Remove-Job
إعادة المحاولة ومعالجة الأخطاء
في التشغيل الحقيقي تظهر أخطاء عابرة مثل ERROR_NO_SLOT_AVAILABLE. غلّف الحل بمنطق إعادة محاولة يعتمد على التراجع الأسي، مع التمييز بين الأخطاء القابلة لإعادة المحاولة وتلك التي يجب إيقاف التنفيذ عندها:
function Solve-WithRetry {
param(
[Parameter(Mandatory)]
[string]$ApiKey,
[Parameter(Mandatory)]
[hashtable]$TaskParams,
[int]$MaxRetries = 3
)
$retryableErrors = @(
"ERROR_NO_SLOT_AVAILABLE",
"ERROR_CAPTCHA_UNSOLVABLE"
)
for ($attempt = 0; $attempt -le $MaxRetries; $attempt++) {
if ($attempt -gt 0) {
$delay = [Math]::Pow(2, $attempt) + (Get-Random -Maximum 3)
Write-Host "Retry $attempt/$MaxRetries after $($delay)s..."
Start-Sleep -Seconds $delay
}
try {
$taskId = Submit-CaptchaTask -ApiKey $ApiKey -TaskParams $TaskParams
$result = Get-CaptchaResult -ApiKey $ApiKey -TaskId $taskId
return $result
}
catch {
$errorMsg = $_.Exception.Message
$isRetryable = $retryableErrors | Where-Object { $errorMsg -like "*$_*" }
if (-not $isRetryable -or $attempt -eq $MaxRetries) {
throw
}
Write-Warning "Retryable error: $errorMsg"
}
}
}
الجدولة عبر Task Scheduler
لتشغيل الأتمتة دون تدخل يدوي، سجّل السكربت كمهمة مجدولة تعمل يوميًا في وقت محدد. هذه هي الطريقة التي تحوّل بها الأمثلة السابقة إلى عملية مستمرة على خادم Windows:
نصيحة أمان: لا تكتب مفتاح الـ API داخل ملف السكربت المجدول؛ اقرأه من متغيّر بيئة آمن على الخادم حتى لا يظهر في سجلّات المهام أو نسخ الملفات الاحتياطية.
# Create a scheduled task that runs CAPTCHA automation daily
$action = New-ScheduledTaskAction `
-Execute "powershell.exe" `
-Argument "-ExecutionPolicy Bypass -File C:\Scripts\captcha-automation.ps1"
$trigger = New-ScheduledTaskTrigger -Daily -At "08:00"
Register-ScheduledTask `
-TaskName "CaptchaAutomation" `
-Action $action `
-Trigger $trigger `
-Description "Run daily CAPTCHA automation with CaptchaAI"
استكشاف الأخطاء الشائعة
| خطأ | السبب | الإصلاح |
|---|---|---|
ERROR_WRONG_USER_KEY |
مفتاح API غير صالح | تحقق من المفتاح في لوحة التحكم |
ERROR_ZERO_BALANCE |
الرصيد صفر | اشحن الحساب |
Invoke-RestMethod: SSL/TLS |
عدم تطابق إصدار TLS | أضف [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 |
The response content cannot be parsed |
استجابة غير JSON | استخدم Invoke-WebRequest وحلّل الرد يدويًا |
خطأ Execution policy |
السكربت محظور | شغّل Set-ExecutionPolicy -Scope CurrentUser RemoteSigned |
Cannot convert to double |
خطأ في تحليل الرصيد | استخدم [double]::Parse($response.request) |
الأسئلة الشائعة
كم يستغرق حل الكابتشا وكيف أضبط مهلة الاستطلاع؟
يعتمد الزمن على نوع الكابتشا وحمل الخدمة؛ اختبارات Turnstile عادةً أسرع من reCAPTCHA. ابدأ بفترة استطلاع من 5 ثوانٍ ومهلة قصوى 300 ثانية كما في الأمثلة، ثم اضبط PollIntervalSeconds وMaxWaitSeconds حسب سلوك موقعك المستهدف.
كم عدد المهام المتزامنة التي يمكنني تشغيلها عبر Start-Job؟
يتحدد ذلك بعدد الـ threads في خطتك، لأن CaptchaAI تُسعّر حسب الـ threads المتزامنة لا حسب عدد عمليات الحل. تبدأ خطة BASIC من 15$ شهريًا بـ 5 threads، وترتفع مع الخطط الأعلى، مع عمليات حل غير محدودة داخل كل thread. اضبط عدد وظائف Start-Job المتزامنة بما يتناسب مع حدّ الـ threads في خطتك.
هل تحل CaptchaAI اختبار hCaptcha في PowerShell؟
لا، لا تدعم CaptchaAI حاليًا حل hCaptcha ولا FunCaptcha. الأنواع المغطّاة هنا — reCAPTCHA v2/v3 وCloudflare Turnstile والكابتشا الصورية — مدعومة بشكل كامل، إلى جانب GeeTest v3 وCloudflare Challenge وBLS.
كيف أؤمّن مفتاح الـ API داخل مهمة مجدولة أو خط CI/CD؟
لا تكتب المفتاح داخل السكربت مباشرة. خزّنه كمتغيّر بيئة على الخادم أو كمتغيّر سري في Azure DevOps أو GitHub Actions أو Jenkins، ثم اقرأه في وقت التشغيل عبر $env:CAPTCHAAI_KEY.
مقالات ذات صلة
شغّل أتمتة الكابتشا من سطر أوامر Windows — أنشئ مفتاح الـ API وابدأ البرمجة النصية اليوم.