API-Tutorials

PowerShell + CaptchaAI: Windows-Automatisierungs-CAPTCHA-Lösung

PowerShell ist das Standard-Automatisierungstool unter Windows. Systemadministratoren, QA-Ingenieure und DevOps-Teams nutzen es für Webtests, Formularautomatisierung und Überwachung. Wenn diese Skripte auf CAPTCHAs treffen, wird die HTTP-API von CaptchaAI direkt über Invoke-RestMethod integriert – es müssen keine Module installiert werden.

In diesem Leitfaden wird die Lösung von reCAPTCHA v2/v3, Cloudflare Turnstile und Bild-CAPTCHA mit produktionsbereiten PowerShell-Funktionen und -Skripten behandelt.


Warum PowerShell für CAPTCHA-Automatisierung

  • In Windows integriert – keine Installation erforderlich (PowerShell 5.1+)
  • Invoke-RestMethod – native REST-API-Unterstützung mit automatischer JSON-Analyse
  • Aufgabenplaner – CAPTCHA-abhängige Skripte nativ planen
  • Pipeline-freundlich – Kettenlösung mit nachgelagerter Automatisierung
  • Plattformübergreifend – PowerShell 7+ läuft auch auf Linux und macOS

Voraussetzungen

  • PowerShell 5.1 (Windows) oder PowerShell 7+ (plattformübergreifend)
  • CaptchaAI API-Schlüssel (Holen Sie sich hier eins)
  • Keine zusätzlichen Module erforderlich

Grundlegende Löserfunktionen

Aufgabe senden

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
}

Umfrageergebnis

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"
}

Lösung von reCAPTCHA v2

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-"

Lösung von Cloudflare 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..."

Lösung von reCAPTCHA v3

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
}

Bild-CAPTCHAs lösen

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"

Von URL

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
}

Komplettes Solver-Modul

Speichern als CaptchaAI.psm1:

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

Verwendung des Moduls

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))..."

Senden von Formularen mit gelösten Token

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)"

Paralleles Lösen mit Jobs

$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

Wiederholen Sie den Vorgang mit Fehlerbehandlung

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"
        }
    }
}

Integration geplanter Aufgaben

# 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 mit CaptchaAI"

Fehlerbehebung

Fehler Ursache Beheben
ERROR_WRONG_USER_KEY Ungültiger API-Schlüssel Überprüfen Sie den Schlüssel im Dashboard
ERROR_ZERO_BALANCE Keine Mittel Konto aufladen
Invoke-RestMethod: SSL/TLS TLS-Versionskonflikt Fügen Sie [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 hinzu
The response content cannot be parsed Nicht-JSON-Antwort Verwenden Sie Invoke-WebRequest und analysieren Sie es manuell
Execution policy-Fehler Skript blockiert Führen Sie Set-ExecutionPolicy -Scope CurrentUser RemoteSigned aus
Cannot convert to double Fehler beim Analysieren des Kontostands Verwenden Sie [double]::Parse($response.request)

FAQ

Funktioniert das mit PowerShell 5.1 und 7+?

Ja. Sowohl Invoke-RestMethod als auch Invoke-WebRequest funktionieren in PowerShell 5.1 (Windows integriert) und PowerShell 7+ (plattformübergreifend).

Muss ich irgendwelche Module installieren?

Nein. Die REST-API von CaptchaAI funktioniert mit integrierten PowerShell-Cmdlets. Keine externen Module erforderlich.

Kann ich dies in CI/CD-Pipelines verwenden?

Ja. PowerShell läuft in Azure DevOps, GitHub Actions und Jenkins. Speichern Sie den API-Schlüssel als geheime Variable.

Wie gehe ich mit TLS-Fehlern um?

Fügen Sie [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 oben in Ihrem Skript hinzu.


Verwandte Leitfäden


CAPTCHAs über die Windows-Befehlszeile mit CaptchaAI automatisieren.

Kommentare sind für diesen Artikel deaktiviert.