Hướng Dẫn Thực Hành

Ghi nhật ký có cấu trúc cho hoạt động CAPTCHA

Khi giải CAPTCHA không thành công vào lúc 3 giờ sáng, nhật ký văn bản đơn giản như "Error solving captcha" sẽ không giúp ích được gì. Nhật ký JSON có cấu trúc với ID tác vụ, loại hình ảnh xác thực, thời gian giải quyết và mã lỗi cho phép bạn lọc, tìm kiếm và cảnh báo chính xác những gì đã xảy ra.


Tại sao ghi nhật ký có cấu trúc

Văn bản thuần túy JSON có cấu trúc
Captcha solved in 12.3s {"event":"captcha_solved","task_id":"abc123","type":"recaptcha_v2","solve_time_ms":12300}
Khó phân tích Máy có thể đọc được
Tìm kiếm chỉ theo Grep Lọc theo trường bất kỳ
Không có mối tương quan Liên kết ID tác vụ gửi → thăm dò → tiêm

Python: nhật ký cấu trúc

import structlog
import time

structlog.configure(
    processors=[
        structlog.processors.TimeStamper(fmt="iso"),
        structlog.processors.add_log_level,
        structlog.processors.JSONRenderer(),
    ],
    logger_factory=structlog.PrintLoggerFactory(),
)

log = structlog.get_logger()

Ghi nhật ký vòng đời giải quyết

import requests

API_KEY = "YOUR_API_KEY"

def solve_captcha(captcha_type, sitekey, page_url, proxy=None):
    solve_log = log.bind(
        captcha_type=captcha_type,
        site_url=page_url,
        sitekey=sitekey[:12] + "...",
    )

    # Submit
    start = time.time()
    solve_log.info("captcha_submit_start")

    resp = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": API_KEY,
        "method": "userrecaptcha",
        "googlekey": sitekey,
        "pageurl": page_url,
        "json": "1",
    }).json()

    if resp["status"] != 1:
        solve_log.error("captcha_submit_failed", error=resp["request"])
        return None

    task_id = resp["request"]
    submit_ms = int((time.time() - start) * 1000)
    solve_log = solve_log.bind(task_id=task_id)
    solve_log.info("captcha_submitted", submit_ms=submit_ms)

    # Poll
    for attempt in range(24):
        time.sleep(5)
        result = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": API_KEY, "action": "get", "id": task_id, "json": "1"
        }).json()

        if result["status"] == 1:
            solve_ms = int((time.time() - start) * 1000)
            solve_log.info(
                "captcha_solved",
                solve_time_ms=solve_ms,
                poll_attempts=attempt + 1,
                token_length=len(result["request"]),
            )
            return result["request"]

        if result["request"] != "CAPCHA_NOT_READY":
            solve_log.error(
                "captcha_solve_failed",
                error=result["request"],
                poll_attempts=attempt + 1,
            )
            return None

    solve_log.warning("captcha_solve_timeout", poll_attempts=24)
    return None

Đầu ra:

{"event":"captcha_submit_start","captcha_type":"recaptcha_v2","site_url":"https://example.com","sitekey":"6Le-wvkSAAAA...","timestamp":"2025-07-15T10:30:00Z","level":"info"}
{"event":"captcha_submitted","task_id":"71845302","submit_ms":245,"timestamp":"2025-07-15T10:30:00Z","level":"info"}
{"event":"captcha_solved","task_id":"71845302","solve_time_ms":18230,"poll_attempts":4,"token_length":580,"timestamp":"2025-07-15T10:30:18Z","level":"info"}

Node.js: pino

const pino = require('pino');

const log = pino({
  level: 'info',
  timestamp: pino.stdTimeFunctions.isoTime,
});

Ghi nhật ký vòng đời giải quyết

const axios = require('axios');

const API_KEY = 'YOUR_API_KEY';

async function solveCaptcha(captchaType, sitekey, pageUrl) {
  const taskLog = log.child({
    captchaType,
    siteUrl: pageUrl,
    sitekey: sitekey.substring(0, 12) + '...',
  });

  const start = Date.now();
  taskLog.info('captcha_submit_start');

  const submit = await axios.post('https://ocr.captchaai.com/in.php', null, {
    params: {
      key: API_KEY, method: 'userrecaptcha',
      googlekey: sitekey, pageurl: pageUrl, json: 1,
    },
  });

  if (submit.data.status !== 1) {
    taskLog.error({ error: submit.data.request }, 'captcha_submit_failed');
    return null;
  }

  const taskId = submit.data.request;
  const boundLog = taskLog.child({ taskId });
  boundLog.info({ submitMs: Date.now() - start }, 'captcha_submitted');

  for (let attempt = 1; attempt <= 24; attempt++) {
    await new Promise(r => setTimeout(r, 5000));
    const poll = await axios.get('https://ocr.captchaai.com/res.php', {
      params: { key: API_KEY, action: 'get', id: taskId, json: 1 },
    });

    if (poll.data.status === 1) {
      boundLog.info({
        solveTimeMs: Date.now() - start,
        pollAttempts: attempt,
        tokenLength: poll.data.request.length,
      }, 'captcha_solved');
      return poll.data.request;
    }

    if (poll.data.request !== 'CAPCHA_NOT_READY') {
      boundLog.error({ error: poll.data.request, pollAttempts: attempt }, 'captcha_solve_failed');
      return null;
    }
  }

  boundLog.warn({ pollAttempts: 24 }, 'captcha_solve_timeout');
  return null;
}

Tham chiếu trường nhật ký

trường loại Mô tả
event chuỗi Tên sự kiện: captcha_submitted, captcha_solved, v.v.
task_id chuỗi ID nhiệm vụ CaptchaAI cho mối tương quan
captcha_type chuỗi recaptcha_v2, turnstile, image, v.v.
site_url chuỗi URL trang mục tiêu
solve_time_ms số nguyên Tổng thời gian từ khi gửi đến khi giải quyết
poll_attempts số nguyên Số lượng yêu cầu thăm dò ý kiến được thực hiện
error chuỗi Mã lỗi từ CaptchaAI
token_length số nguyên Độ dài của mã thông báo được trả về

Lọc và cảnh báo

Tìm tất cả các thất bại trong giờ qua

# With jq
cat captcha.log | jq 'select(.level == "error" and .event == "captcha_solve_failed")'

Cảnh báo tỷ lệ thất bại cao

# Count errors vs successes in a rolling window
from collections import deque

class ErrorRateMonitor:
    def __init__(self, window_size=100, threshold=0.2):
        self.results = deque(maxlen=window_size)
        self.threshold = threshold

    def record(self, success):
        self.results.append(success)
        if len(self.results) >= 50:
            error_rate = 1 - sum(self.results) / len(self.results)
            if error_rate > self.threshold:
                log.warning(
                    "captcha_error_rate_high",
                    error_rate=round(error_rate, 3),
                    window=len(self.results),
                )

Khắc phục sự cố

Vấn đề Nguyên nhân Cách xử lý
Nhật ký quá dài dòng Ghi lại mọi nỗ lực thăm dò ý kiến Chỉ ghi nhật ký các sự kiện gửi, giải quyết và thất bại
Không thể liên kết các sự kiện Thiếu ID nhiệm vụ Liên kết sớm task_id với log.bind() hoặc log.child()
Nhật ký không thể tìm kiếm được Định dạng văn bản thuần túy Chuyển sang JSON bằng structlog hoặc pino
Dữ liệu nhạy cảm trong nhật ký Ghi nhật ký khóa API đầy đủ Không bao giờ ghi lại khóa API; cắt bớt khóa trang web

Câu hỏi thường gặp

Tôi có nên đăng nhập mã thông báo CAPTCHA không?

Ghi lại độ dài mã thông báo, không phải mã thông báo đầy đủ. Mã thông báo có thể có hơn 500 ký tự và thêm khối lượng nhật ký không cần thiết.

Cấp độ nhật ký nào cho CAPCHA_NOT_READY?

Tuyệt đối không ghi lại thông tin đó - điều này được mong đợi trong quá trình bỏ phiếu. Chỉ ghi lại kết quả cuối cùng.


Xây dựng quy trình làm việc CAPTCHA có thể quan sát được bằng CaptchaAI

Nhận khóa API của bạn tạicaptchaai.com.


Hướng dẫn liên quan

Os comentários estão desativados para este artigo.