DevOps 与扩展

Docker + CaptchaAI:容器化验证码解决

在 Docker 容器中运行 CAPTCHA 求解器可确保一致的环境、轻松扩展和干净的部署。本指南涵盖了从基本 Dockerfile 到多工作 Docker Compose 设置的所有内容。


基本 Dockerfile

FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY solver.py .

# API key passed at runtime, not baked into image
ENV CAPTCHAAI_KEY=""

CMD ["python", "solver.py"]

需求.txt:

requests>=2.31.0

求解器脚本

# solver.py
import os
import sys
import requests
import time


def solve_recaptcha(api_key, site_key, page_url):
    """Solve reCAPTCHA v2 using CaptchaAI."""
    resp = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": api_key,
        "method": "userrecaptcha",
        "googlekey": site_key,
        "pageurl": page_url,
        "json": 1,
    }, timeout=30)
    result = resp.json()

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

    task_id = result["request"]

    # Poll for result
    for _ in range(24):  # 120s max
        time.sleep(5)
        resp = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": api_key,
            "action": "get",
            "id": task_id,
            "json": 1,
        }, timeout=15)
        data = resp.json()
        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")


if __name__ == "__main__":
    api_key = os.environ.get("CAPTCHAAI_KEY")
    if not api_key:
        print("Error: CAPTCHAAI_KEY environment variable required")
        sys.exit(1)

    site_key = os.environ.get("SITE_KEY", "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-")
    page_url = os.environ.get("PAGE_URL", "https://example.com")

    token = solve_recaptcha(api_key, site_key, page_url)
    print(f"Token: {token[:50]}...")

构建并运行

# Build
docker build -t captchaai-solver .

# Run with API key from environment
docker run --rm \
  -e CAPTCHAAI_KEY="YOUR_API_KEY" \
  -e SITE_KEY="TARGET_SITE_KEY" \
  -e PAGE_URL="https://example.com" \
  captchaai-solver

多阶段构建(生产)

具有安全最佳实践的较小图像:

# Build stage
FROM python:3.11-slim AS builder

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --target=/app/deps -r requirements.txt

# Runtime stage
FROM python:3.11-slim

# Run as non-root
RUN useradd --create-home solver
USER solver

WORKDIR /home/solver/app

COPY --from=builder /app/deps /home/solver/app/deps
COPY solver.py .

ENV PYTHONPATH=/home/solver/app/deps
ENV PYTHONUNBUFFERED=1

CMD ["python", "solver.py"]

Docker Compose:多工作人员设置

跨多个容器扩展 CAPTCHA 解决方案:

# docker-compose.yml
version: "3.8"

services:
  solver-worker:
    build: .
    environment:

      - CAPTCHAAI_KEY=${CAPTCHAAI_KEY}
    restart: unless-stopped
    deploy:
      replicas: 4
      resources:
        limits:
          memory: 256M
          cpus: "0.25"

  redis:
    image: redis:7-alpine
    ports:

      - "6379:6379"

  queue-worker:
    build:
      context: .
      dockerfile: Dockerfile.worker
    environment:

      - CAPTCHAAI_KEY=${CAPTCHAAI_KEY}
      - REDIS_URL=redis://redis:6379
    depends_on:

      - redis
    deploy:
      replicas: 4

基于队列的工作线程

# queue_worker.py
import os
import json
import time
import redis
import requests


def process_task(api_key, task_data):
    """Process a single CAPTCHA task from the queue."""
    resp = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": api_key,
        "method": task_data["method"],
        "json": 1,
        **task_data["params"],
    }, timeout=30)
    result = resp.json()

    if result.get("status") != 1:
        return {"error": result.get("request")}

    task_id = result["request"]

    for _ in range(24):
        time.sleep(5)
        resp = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": api_key, "action": "get",
            "id": task_id, "json": 1,
        }, timeout=15)
        data = resp.json()
        if data["request"] != "CAPCHA_NOT_READY":
            if data.get("status") == 1:
                return {"token": data["request"]}
            return {"error": data["request"]}

    return {"error": "timeout"}


def main():
    api_key = os.environ["CAPTCHAAI_KEY"]
    redis_url = os.environ.get("REDIS_URL", "redis://localhost:6379")
    r = redis.from_url(redis_url)

    print("Worker started, waiting for tasks...")
    while True:
        _, raw = r.blpop("captcha:tasks")
        task = json.loads(raw)
        task_id = task.get("id", "unknown")

        print(f"Processing task {task_id}...")
        result = process_task(api_key, task)

        r.hset("captcha:results", task_id, json.dumps(result))
        print(f"Task {task_id} done: {'ok' if 'token' in result else 'error'}")


if __name__ == "__main__":
    main()

环境变量管理

# .env file (never commit to Git)
CAPTCHAAI_KEY=your_api_key_here

# .gitignore
echo ".env" >> .gitignore

# Run with .env file
docker compose --env-file .env up -d

# Scale workers
docker compose up -d --scale queue-worker=8

故障排除

问题 原因 处理方式
容器立即退出 缺少 CAPTCHAAI_KEY 通证-e CAPTCHAAI_KEY=...
DNS解析失败 无网络访问 检查 Docker 网络设置
内存使用率高 并发请求过多 限制容器内存和并发数
图像中暴露的 API 密钥 键入 Dockerfile 使用环境变量或秘密

常问问题

我应该将 API 密钥烘焙到 Docker 镜像中吗?

绝不。始终在运行时将 API 密钥作为环境变量传递或使用 Docker 机密。将密钥烘焙成图像存在安全风险。

我应该运行多少个容器?

从 4 个工作人员开始,然后根据吞吐量需求进行扩展。每个 Worker 可以处理 5-10 个并发求解,因此 4 个 Worker 支持 20-40 个并发任务。

我可以使用 Docker 机密吗?

是的。 Docker Swarm 和 Kubernetes 都支持 Secret。将它们挂载为文件并从 /run/secrets/captchaai_key 中读取。


相关指南


将您的求解器容器化 –获取CaptchaAI今天。

该文章已禁用评论。