Use Cases

CAPTCHA İşleme ile Reklam Doğrulama İş Akışları

Reklam doğrulama otomasyonunda hattı asıl durduran şey nadiren kodunuzdur; yayıncı sayfalarında beliren reCAPTCHA ve Cloudflare Turnstile ekranlarıdır. CaptchaAI bu doğrulamaları API üzerinden çözer, böylece tarayıcınız yüzlerce sayfayı gezerken doğrulama duvarına çarpıp durmaz. Aşağıda bir doğrulama işini uçtan uca, CAPTCHA çözümü dahil nasıl kuracağınızı gösteriyoruz.

Reklam doğrulaması neyi kontrol eder, CAPTCHA neden araya girer?

Kontrol Ne bakılır CAPTCHA neden devreye girer
Reklam yerleşimi Reklam sayfanın görünür üst bölümünde mi çıkıyor? Otomatik sayfa ziyaretleri bot tespitini tetikler
Marka güvenliği Reklam zararlı içeriğin yanında görünmüyor mu? Toplu URL kontrolü veri kazımaya benzer
Görüntülenebilirlik Reklam kullanıcıya gerçekten göründü mü? Cloudflare, headless tarayıcıları işaretler
Coğrafi hedefleme Doğru bölgede doğru reklam gösteriliyor mu? Proxy trafiği CAPTCHA'ları tetikler
Rakip izleme Rakipler aynı sayfalarda hangi reklamları veriyor? Yüksek hacimli reklam sorguları şüphe çeker

İstanbul'daki bir performans pazarlama ajansının müşteri bannerlarını yüzlerce haber ve e-ticaret sitesinde her sabah doğruladığını düşünün. Liste büyüdükçe sayfaların bir kısmı reCAPTCHA veya Turnstile ile yanıt verir ve manuel kontrol imkânsız hale gelir. Not: yayıncı sayfalarından toplanan içerik kişisel veri barındırıyorsa KVKK kapsamına girer — doğrulamayı yetkiniz olan alanlarla sınırlayın.

Tek sayfalık doğrulama akışını kurma

Aşağıdaki Python betiği bir yayıncı sayfasını alır, sayfada reCAPTCHA varsa solve_captcha yardımcısıyla CaptchaAI'ye gönderip token'ı geri enjekte eder, ardından reklam etiketlerini tespit eder. Yardımcı görevi in.php'ye gönderir ve sonucu res.php'den sorgular:

import requests
import time
import re
import json
import os
from datetime import datetime

API_KEY = os.environ["CAPTCHAAI_API_KEY"]


def solve_captcha(method, params):
    params["key"] = API_KEY
    params["method"] = method

    resp = requests.get("https://ocr.captchaai.com/in.php", params=params)
    if not resp.text.startswith("OK|"):
        raise Exception(resp.text)

    task_id = resp.text.split("|")[1]
    for _ in range(60):
        time.sleep(5)
        result = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": API_KEY, "action": "get", "id": task_id,
        })
        if result.text == "CAPCHA_NOT_READY":
            continue
        if result.text.startswith("OK|"):
            return result.text.split("|", 1)[1]
        raise Exception(result.text)
    raise TimeoutError()


def verify_ad_placement(url, session):
    """Verify ad placement on a publisher page."""
    resp = session.get(url)

    # Solve CAPTCHA if present
    match = re.search(r'data-sitekey=["\']([A-Za-z0-9_-]+)["\']', resp.text)
    if match:
        token = solve_captcha("userrecaptcha", {
            "googlekey": match.group(1),
            "pageurl": url,
        })
        resp = session.post(url, data={"g-recaptcha-response": token})

    html = resp.text

    # Check for ad elements
    result = {
        "url": url,
        "timestamp": datetime.utcnow().isoformat(),
        "ads_found": [],
        "brand_safety": True,
        "captcha_solved": match is not None,
    }

    # Detect ad tags
    ad_patterns = [
        (r'googletag\.pubads', "Google Ad Manager"),
        (r'doubleclick\.net', "DFP/DoubleClick"),
        (r'ad\.doubleclick', "DoubleClick"),
        (r'amazon-adsystem', "Amazon Ads"),
        (r'criteo\.com/.*\.js', "Criteo"),
    ]

    for pattern, name in ad_patterns:
        if re.search(pattern, html):
            result["ads_found"].append(name)

    # Brand safety check — flag problematic content
    safety_keywords = [
        "violence", "hate speech", "explicit",
        "gambling", "illegal",
    ]
    page_text = re.sub(r'<[^>]+>', '', html).lower()
    for keyword in safety_keywords:
        if keyword in page_text:
            result["brand_safety"] = False
            break

    return result


def run_verification(urls, output_file="verification_report.json"):
    """Run ad verification across multiple publisher URLs."""
    session = requests.Session()
    session.headers["User-Agent"] = (
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
        "AppleWebKit/537.36 Chrome/120.0.0.0"
    )

    results = []
    for i, url in enumerate(urls):
        try:
            result = verify_ad_placement(url, session)
            results.append(result)
            ads = ", ".join(result["ads_found"]) or "None"
            safe = "SAFE" if result["brand_safety"] else "UNSAFE"
            print(f"  [{i+1}/{len(urls)}] {url}: {ads} [{safe}]")
        except Exception as e:
            results.append({
                "url": url,
                "error": str(e),
                "timestamp": datetime.utcnow().isoformat(),
            })
            print(f"  [{i+1}/{len(urls)}] {url}: ERROR - {e}")

        time.sleep(2)

    with open(output_file, "w") as f:
        json.dump(results, f, indent=2)

    # Summary
    total = len(results)
    safe = sum(1 for r in results if r.get("brand_safety"))
    captchas = sum(1 for r in results if r.get("captcha_solved"))
    errors = sum(1 for r in results if "error" in r)

    print(f"\n  Total: {total} | Safe: {safe} | CAPTCHAs solved: {captchas} | Errors: {errors}")

    return results


# Publisher URLs to verify
publisher_urls = [
    "https://publisher1.com/article/tech-news",
    "https://publisher2.com/sports/latest",
    "https://publisher3.com/finance/markets",
]

run_verification(publisher_urls)

Betik sonuçları verification_report.json dosyasına yazar ve her URL için bulunan reklam ağlarını, marka güvenliği durumunu ve CAPTCHA'nın çözülüp çözülmediğini raporlar.

Cloudflare korumalı yayıncılarda ölçeklendirme

Premium yayıncıların çoğu Cloudflare kullanır. Sayfa hem Turnstile widget'ıyla hem de tam doğrulama akışıyla (403 + cf-browser-verification) gelebilir; aşağıdaki fonksiyon ikisini de ele alır:

def handle_cloudflare(url, session):
    """Handle Cloudflare-protected publisher pages."""
    resp = session.get(url)

    if "cf-turnstile" in resp.text:
        match = re.search(r'data-sitekey=["\']([^"\']+)', resp.text)
        if match:
            token = solve_captcha("turnstile", {
                "sitekey": match.group(1),
                "pageurl": url,
            })
            return session.post(url, data={
                "cf-turnstile-response": token,
            })

    if resp.status_code == 403 and "cf-browser-verification" in resp.text:
        data = solve_captcha("cloudflare_challenge", {
            "pageurl": url,
            "proxy": "user:pass@proxy:port",
            "proxytype": "HTTP",
        })
        # Parse qa_session_cookie and use same proxy
        return data

    return resp

Coğrafi hedeflemeyi doğru kurma

Reklam yerleşimi bölgeye göre değişir; İzmir'den görünen reklam Frankfurt'tan görünenle aynı olmayabilir. Doğru sonucu almak için isteklerinizi hedef coğrafyadaki proxy'ler üzerinden yönlendirin ve aynı bağlamı çözüm adımına da taşıyın. CaptchaAI çözüm isteğine proxy parametreleri iletmenize olanak tanır; böylece CAPTCHA, tarayıcınızın çıktığı IP ile aynı bölgeden çözülür ve doğrulama bağlamı bozulmaz. Bölge başına ayrı bir çalışma listesi tutmak, reklam ağı imzalarını doğru bölgeye eşlemenizi ve raporlarınızı bölge bazında temiz tutmanızı sağlar.

Doğrulama işini üretimde güvenilir tutma

Yüzlerce sayfalık bir listede tek tük hatalar kaçınılmazdır: bir sayfa zaman aşımına uğrar, bir CAPTCHA beklenenden yavaş çözülür ya da yayıncı geçici olarak 429 döndürür. İşi kırılgan bir adımlar zincirine çevirmemek için birkaç alışkanlık yeterli:

  • Başarısız istekleri hemen tekrar denemek yerine üstel geri çekilme (exponential backoff) uygulayın; her denemede bekleme süresini artırın.
  • Çözüm sorgusuna bir zaman aşımı koyun — örnekteki 60 sorgu × 5 saniye gibi — ve süresi dolan görevi hataya düşürüp sıradaki URL'ye geçin.
  • Her URL'nin sonucunu (çözülen CAPTCHA, bulunan reklam ağları, hata mesajı) kaydedin; betikteki verification_report.json çıktısı bunun için iyi bir başlangıçtır.
  • Aynı siteye ardışık istekleri seyreltin; istekler arasına gecikme koymak hem istek sınırlamasını hem de gereksiz CAPTCHA tetiklenmesini azaltır.

Bu dört alışkanlık, gece boyunca çalışan bir doğrulama işini sabah eksiksiz ve temiz bir raporla karşılamanızı sağlar; hatalı sayfaları ayrı bir listede toplayıp yalnızca onları yeniden çalıştırmak da toplam süreyi kısaltır.

Doğrulama hacmine göre plan seçimi

CaptchaAI thread başına faturalandırır; her thread aynı anda tek bir CAPTCHA çözer ve çözüm bitince sıradaki işi alır. Küçük listeler için BASIC ($15/ay, 5 thread) yeterlidir; onlarca yayıncıyı paralel tarıyorsanız STANDARD ($30/ay, 15 thread) veya ADVANCE ($90/ay, 50 thread) eşzamanlı çözümü artırır. Çözüm sayısı plan başına sınırsızdır. Faturalandırma USD olduğundan aylık maliyetiniz TL kurundan bağımsız kalır. Güncel fiyatlar için https://captchaai.com/pricing sayfasına bakın.

SSS

Reklam doğrulamada hangi CAPTCHA türlerini çözebilirim?

CaptchaAI reCAPTCHA v2 ve v3 (Enterprise dahil), Cloudflare Turnstile ve Challenge, GeeTest v3 ile görüntü/OCR ve grid CAPTCHA'larını çözer. Yayıncı sayfalarında en sık bunlarla karşılaşırsınız. hCaptcha ve FunCaptcha şu an desteklenmez.

Betik reklamları nasıl tespit ediyor?

Örnek, sayfa HTML'inde Google Ad Manager, DoubleClick, Amazon Ads ve Criteo gibi ağların imzalarını arar. Yeni bir ağ eklemek için ad_patterns listesine bir regex ve etiket eklemeniz yeterlidir; marka güvenliği kontrolü de aynı biçimde safety_keywords üzerinden genişletilir.

Doğrulama hacmim için kaç thread gerekir?

Thread sayısı aynı anda kaç çözümün işleneceğini belirler. Küçük ve sıralı bir liste için birkaç thread yeter; yüzlerce sayfayı paralel doğruluyorsanız daha yüksek thread'li bir plan gecikmeyi azaltır. Çözüm sayısı plan başına sınırsız olduğundan tek değişken eşzamanlılıktır.

Bu yöntem video reklam doğrulaması için de çalışır mı?

Yöntem görüntülü (display) ve yerel (native) reklamlar için uygundur. Video reklam doğrulaması genellikle Selenium veya Playwright ile gerçek tarayıcı oluşturmayı gerektirir; CAPTCHA çözümünü aynı API'yle bu akışa da eklersiniz.

Topladığım yayıncı verileri KVKK kapsamına girer mi?

Kişisel veri içeren içerik topluyorsanız KVKK yükümlülükleri geçerlidir. Doğrulamayı yetkiniz olan alanlar ve QA amaçlı akışlarla sınırlayın; CaptchaAI yalnızca sayfadaki CAPTCHA'yı çözer, veri toplama sorumluluğu sizde kalır.

İlgili Kılavuzlar

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