Eğitimler

CAPTCHA İşlemleri için Yapılandırılmış Günlük Kaydı

CAPTCHA çözümü sabah 3'te başarısız olduğunda "Error solving captcha" gibi düz metin günlükleri yardımcı olmaz. Görev kimlikleri, captcha türleri, çözüm süreleri ve hata kodları içeren yapılandırılmış JSON günlükleri, tam olarak neyin yanlış gittiğini filtrelemenize, aramanıza ve uyarmanıza olanak tanır.


Neden yapılandırılmış günlük kaydı

Düz metin Yapılandırılmış JSON
Captcha solved in 12.3s {"event":"captcha_solved","task_id":"abc123","type":"recaptcha_v2","solve_time_ms":12300}
Ayrıştırılması zor Makine tarafından okunabilir
Yalnızca Grep araması Herhangi bir alana göre filtrele
Korelasyon yok Görev Kimliği bağlantıları gönder – anket – enjekte

Python: yapı günlüğü

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

Çözüm yaşam döngüsünü günlüğe kaydetme

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

Çıktı:

{"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,
});

Çözüm yaşam döngüsünü günlüğe kaydetme

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

Günlük alanları referansı

Alan Tür Açıklama
event dize Etkinlik adı: captcha_submitted, captcha_solved, vb.
task_id dize Korelasyon için CaptchaAI görev kimliği
captcha_type dize recaptcha_v2, turnstile, image, vb.
site_url dize Hedef sayfa URL'si
solve_time_ms tamsayı Gönderimden çözülene kadar geçen toplam süre
poll_attempts tamsayı Yapılan anket isteği sayısı
error dize CaptchaAI'den gelen hata kodu
token_length tamsayı İade edilen jetonun uzunluğu

Filtreleme ve uyarı

Son saatteki tüm arızaları bulun

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

Yüksek başarısızlık oranı konusunda uyarı

# 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),
                )

Sorun giderme

Sorun Sebep Düzeltme
Günlükler çok ayrıntılı Her anket girişiminin günlüğe kaydedilmesi Yalnızca gönderilen, çözülen ve başarısız olan olayları günlüğe kaydet
Olaylar ilişkilendirilemiyor Eksik görev kimliği task_id'yi log.bind() veya log.child() ile erken bağlayın
Günlükler aranamıyor Düz metin formatı structlog veya pino ile JSON'a geçin
Günlüklerdeki hassas veriler Tam API anahtarının günlüğe kaydedilmesi API anahtarlarını hiçbir zaman kaydetmeyin; site anahtarlarını kısalt

SSS

CAPTCHA jetonunu kaydetmeli miyim?

Tokenın tamamını değil, token uzunluğunu kaydedin. Belirteçler 500'den fazla karakter olabilir ve gereksiz günlük hacmi ekleyebilir.

CAPCHA_NOT_READY için hangi günlük düzeyi?

Hiçbir şekilde kaydetmeyin, oylama sırasında olması beklenir. Yalnızca nihai sonucu kaydedin.


CaptchaAI ile gözlemlenebilir CAPTCHA iş akışları oluşturun

API anahtarınızı şu adresten alın:captchaai.com.


İlgili kılavuzlar

Bu makale için yorumlar devre dışı bırakılmıştır.