DevOps & Skalabilitas

AWS Lambda + CaptchaAI: Pemecahan CAPTCHA Serverless

AWS Lambda menangani penyelesaian CAPTCHA tanpa mengelola server. Bayar hanya saat menyelesaikan, menskalakan secara otomatis, dan berintegrasi dengan API Gateway, SQS, atau Step Functions.


Pengendali Lambda

# lambda_function.py
import json
import os
import time
import urllib.request
import urllib.parse


def lambda_handler(event, context):
    """AWS Lambda handler for CaptchaAI solving."""
    api_key = os.environ["CAPTCHAAI_KEY"]

    # Parse input
    body = json.loads(event.get("body", "{}")) if isinstance(event.get("body"), str) else event

    method = body.get("method", "userrecaptcha")
    params = body.get("params", {})

    try:
        token = solve_captcha(api_key, method, params)
        return {
            "statusCode": 200,
            "body": json.dumps({"token": token}),
        }
    except Exception as e:
        return {
            "statusCode": 500,
            "body": json.dumps({"error": str(e)}),
        }


def solve_captcha(api_key, method, params, timeout=90):
    """Solve CAPTCHA using CaptchaAI API."""
    # Submit task
    submit_data = urllib.parse.urlencode({
        "key": api_key,
        "method": method,
        "json": 1,
        **params,
    }).encode()

    req = urllib.request.Request(
        "https://ocr.captchaai.com/in.php",
        data=submit_data,
    )
    with urllib.request.urlopen(req, timeout=30) as resp:
        result = json.loads(resp.read())

    if result.get("status") != 1:
        raise RuntimeError(f"Submit error: {result.get('request')}")

    task_id = result["request"]

    # Poll for result
    start = time.time()
    while time.time() - start < timeout:
        time.sleep(5)
        poll_url = (
            f"https://ocr.captchaai.com/res.php"
            f"?key={api_key}&action=get&id={task_id}&json=1"
        )
        with urllib.request.urlopen(poll_url, timeout=15) as resp:
            data = json.loads(resp.read())

        if data["request"] != "CAPCHA_NOT_READY":
            if data.get("status") == 1:
                return data["request"]
            raise RuntimeError(f"Solve error: {data['request']}")

    raise TimeoutError("Solve timeout")

Amankan Kunci API dengan Manajer Rahasia

import json
import boto3


def get_api_key():
    """Retrieve CaptchaAI key from AWS Secrets Manager."""
    client = boto3.client("secretsmanager")
    response = client.get_secret_value(SecretId="captchaai/api-key")
    secret = json.loads(response["SecretString"])
    return secret["api_key"]

Simpan rahasianya:

aws secretsmanager create-secret \
  --name captchaai/api-key \
  --secret-string '{"api_key":"YOUR_API_KEY"}'

Templat SAM (Infrastruktur sebagai Kode)

# template.yaml
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31

Globals:
  Function:
    Timeout: 120
    MemorySize: 256
    Runtime: python3.11

Resources:
  CaptchaSolverFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: lambda_function.lambda_handler
      Environment:
        Variables:
          CAPTCHAAI_KEY: !Sub "{{resolve:secretsmanager:captchaai/api-key:SecretString:api_key}}"
      Events:
        SolveApi:
          Type: Api
          Properties:
            Path: /solve
            Method: post
      Policies:

        - AWSSecretsManagerGetSecretValuePolicy:
            SecretArn: !Sub "arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:captchaai/api-key-*"

Outputs:
  SolveApiUrl:
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/solve"

Menyebarkan

# Build and deploy
sam build
sam deploy --guided

# Test
curl -X POST https://YOUR_API_ID.execute-api.us-east-1.amazonaws.com/Prod/solve \
  -H "Content-Type: application/json" \
  -d '{
    "method": "userrecaptcha",
    "params": {
      "googlekey": "SITE_KEY",
      "pageurl": "https://example.com"
    }
  }'

Pemrosesan Batch yang Dipicu SQS

Memproses tugas CAPTCHA dari antrean SQS:

import json
import os
import time
import urllib.request
import urllib.parse


def sqs_handler(event, context):
    """Process CAPTCHA tasks from SQS queue."""
    api_key = os.environ["CAPTCHAAI_KEY"]
    results = []

    for record in event["Records"]:
        task = json.loads(record["body"])
        try:
            token = solve_captcha(
                api_key,
                task["method"],
                task["params"],
            )
            results.append({
                "task_id": task.get("id"),
                "status": "success",
                "token": token[:50],
            })
        except Exception as e:
            results.append({
                "task_id": task.get("id"),
                "status": "error",
                "error": str(e),
            })

    return {"results": results}

Pertimbangan Lambda

Faktor Nilai
Waktu tunggu maksimal 15 menit (disetel ke 2 menit untuk sebagian besar CAPTCHA)
Memori Cukup 256 MB (tidak ada pemrosesan berat)
Konkurensi Default 1000 bersamaan (permintaan peningkatan jika diperlukan)
Awal dingin ~500ms untuk Python (dapat diabaikan vs waktu penyelesaian)
Biaya ~$0,0001 per penyelesaian (hanya komputasi)
Ketergantungan Gunakan urllib (bawaan) untuk menghindari lapisan Lambda

Pemecahan Masalah

Masalah Penyebab Solusi
Waktu fungsi habis Batas waktu Lambda < waktu penyelesaian Setel batas waktu ke 120 detik+
Izin ditolak ke secret Kebijakan IAM tidak ada Tambahkan kebijakan baca SecretsManager
Cold start menambah latensi Panggilan yang jarang Gunakan provisioned concurrency
Kesalahan impor untuk requests Tidak dibundel di Lambda Gunakan urllib.request (bawaan) atau tambahkan layer

Pertanyaan Umum

Apakah Lambda hemat biaya untuk penyelesaian CAPTCHA?

Ya. Dengan ~$0,0001 per pemanggilan (256MB, 60 detik), Lambda menambahkan biaya yang dapat diabaikan selain biaya API CaptchaAI. Anda menghindari biaya server selama waktu idle.

Bagaimana dengan batas waktu 15 menit Lambda?

Kebanyakan CAPTCHA diselesaikan dalam 10-60 detik. Atur batas waktu Lambda Anda menjadi 120 detik. Untuk tipe kompleks seperti reCAPTCHA Enterprise, gunakan 180 detik.

Bisakah saya menggunakan lapisan Lambda untuk perpustakaan permintaan?

Ya, tapi urllib.request (bawaan) berfungsi dengan baik untuk API HTTP sederhana CaptchaAI. Hal ini menghindari manajemen lapisan sepenuhnya.


Panduan Terkait

  • Azure Functions + CaptchaAI
  • AWS SNS + CaptchaAI: Event-Driven CAPTCHA

Jalankan serverless – dapatkan kunci CaptchaAI Anda hari ini.

Komentar dinonaktifkan untuk artikel ini.