Use Cases

التحقق من الإعلانات على المواقع المحمية بـ CAPTCHA

يتطلب التحقق الإعلاني المرور على عدد كبير من صفحات الناشرين للتأكد من موضع الإعلان، وسلامة السياق الذي يظهر فيه، وقابلية عرضه الفعلية للمستخدم. لكن كثيرًا من هذه المواقع يفرض اختبارات CAPTCHA بمجرد ملاحظة زيارات آلية متكررة أو استخدام بروكسيات أو متصفحات موحّدة البصمة. يساعدك CaptchaAI على إبقاء سير عمل التحقق قائمًا بدل أن يتوقف عند أول تحدٍّ.

ما الذي تفحصه فرق التحقق الإعلاني؟

عنصر الفحص الوصف لماذا قد يظهر CAPTCHA؟
موضع الإعلان هل يظهر الإعلان داخل الجزء المرئي أو في المكان المتفق عليه؟ الزيارات الآلية المتكررة تبدو كسلوك روبوتي واضح
سلامة العلامة التجارية هل يظهر الإعلان بجوار محتوى حساس أو غير مناسب؟ المسح الجماعي لعدد كبير من الصفحات يشبه أنشطة الكشط المكثف
قابلية العرض هل تم تحميل الإعلان وعرضه فعلاً؟ المتصفحات عديمة الواجهة أو البيئات الموحدة قد تُرصد سريعًا
الاستهداف الجغرافي هل يظهر الإعلان الصحيح في الدولة أو المدينة المطلوبة؟ استخدام البروكسيات أو تبديل المناطق يرفع احتمالية التحدي
مراقبة المنافسين ما نوع الإعلانات التي يعرضها المنافسون وعلى أي صفحات؟ ارتفاع عدد الزيارات والاستعلامات قد يفعّل أنظمة الحماية

كلما توسع نطاق التحقق الإعلاني، صار التحدي الحقيقي ليس مجرد فتح الصفحة، بل المحافظة على جلسة قابلة للتنبؤ: حل CAPTCHA عند الحاجة، وإعادة الطلب بالطريقة الصحيحة، وتوثيق ما حدث لكل صفحة تم فحصها.

التنفيذ

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

import requests

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)

الفكرة العملية هنا أن نتيجة كل صفحة لا يجب أن تكون "نجاح/فشل" فقط. من الأفضل تخزين ما إذا تم حل CAPTCHA فعلًا، وما أنواع الشبكات الإعلانية التي تم اكتشافها، وهل ظهرت مؤشرات خطر على سلامة العلامة التجارية. هذا ما يجعل التقرير قابلًا للمراجعة من فريق العمليات أو فريق الامتثال.

التوسع مع الناشرين المحميين بواسطة Cloudflare

يعتمد عدد كبير من الناشرين الكبار على Cloudflare، لذلك تحتاج غالبًا إلى مسارين مختلفين: مسار لتحديات Turnstile الخفيفة، ومسار آخر للتحديات الكاملة أو صفحات الحظر المؤقت.

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 cf_clearance and use same proxy
        return data

    return resp

إذا كنت تعمل على التحقق الجغرافي أو مقارنة الحملات بين أسواق متعددة، فمن المهم أن يظل البروكسي المستخدم أثناء التصفح متسقًا مع البروكسي المستخدم عند تمرير التحدي، وخصوصًا في صفحات الحماية المشددة.

الأسئلة الشائعة

كم عدد الصفحات التي يمكن التحقق منها في الساعة؟

يعتمد ذلك على كثافة ظهور CAPTCHA، وطبيعة الموقع، وحجم التحميل المطلوب لكل صفحة. في بيئات عملية، يمكن لفريق التحقق الإعلاني الوصول إلى مئات الصفحات في الساعة، لكن الرقم الحقيقي يتحدد من خلال معدل التحديات وقيود الحماية الخاصة بكل ناشر.

هل يعمل هذا للتحقق من إعلان الفيديو؟

يعمل هذا الأسلوب جيدًا مع الإعلانات الصورية والإعلانات المدمجة مع المحتوى. أما التحقق من الفيديو أو الإعلانات الديناميكية المعقدة فيحتاج عادةً إلى متصفح فعلي أو أداة مثل Selenium أو Playwright لالتقاط حالة العرض بدقة.

كيف يمكنني التعامل مع مناطق مختلفة؟

استخدم بروكسيات من المناطق الجغرافية التي تريد فحصها، وابقِ إعدادات التصفح متسقة مع تلك المنطقة. يدعم CaptchaAI تمرير بيانات البروكسي بحيث يكون سياق الحل قريبًا من سياق الجلسة الفعلية.

أدلة ذات صلة


إذا كنت تريد تشغيل التحقق الإعلاني على نطاق أوسع مع سجلات يمكن مراجعتها، فابدأ بـ مفتاح CaptchaAI وابنِ مسارًا يجمع بين حل CAPTCHA والتسجيل التشغيلي لكل فحص.

النقاشات (0)

لا توجد تعليقات بعد.

مقالات ذات صلة

Comparisons مقارنة أفضل خدمات حل CAPTCHA في 2025
مقارنة عملية حول مقارنة أفضل خدمات حل CAPTCHA في 2025 تركّز على الفروق في التكلفة والدقة وزمن الاستجابة وسهولة الدمج، مع التأكيد على أن الحكم النهائي يجب أن يعت...

مقارنة عملية حول مقارنة أفضل خدمات حل CAPTCHA في 2025 تركّز على الفروق في التكلفة والدقة وزمن الاستجابة وسهولة...

Apr 22, 2026
DevOps & Scaling النشر باللونين الأزرق والأخضر للبنية الأساسية لحل اختبار CAPTCHA
دليل تشغيلي لـ النشر باللونين الأزرق والأخضر للبنية الأساسية لحل اختبار CAPTCHA يغطّي قرارات البنية، والاعتمادية، والمراقبة، وأنماط الأتمتة المناسبة لتشغيل Capt...

دليل تشغيلي لـ النشر باللونين الأزرق والأخضر للبنية الأساسية لحل اختبار CAPTCHA يغطّي قرارات البنية، والاعتماد...

Apr 25, 2026
DevOps & Scaling حل CAPTCHA بدون خوادم باستخدام AWS Lambda وCaptchaAI
دليل تشغيلي لـ حل CAPTCHA بدون خوادم باستخدام AWS Lambda وCaptcha AI يغطّي قرارات البنية، والاعتمادية، والمراقبة، وأنماط الأتمتة المناسبة لتشغيل Captcha AI في ب...

دليل تشغيلي لـ حل CAPTCHA بدون خوادم باستخدام AWS Lambda وCaptcha AI يغطّي قرارات البنية، والاعتمادية، والمراق...

Apr 20, 2026