Ein reCAPTCHA v2 oder eine Cloudflare-Turnstile-Abfrage auf der Publisher-Seite bringt jede automatisierte Anzeigenprüfung sofort zum Stillstand. Der direkte Weg daran vorbei: CaptchaAI löst die CAPTCHA-Abfrage per API, Ihr Verifizierungs-Crawler ruft die Seite regulär ab und die Pipeline läuft ohne manuellen Eingriff weiter. Anzeigenverifizierung bedeutet, Tausende Publisher-URLs zu besuchen und Platzierung, Markensicherheit und Geo-Targeting zu prüfen – genau dieser Massenzugriff löst die Schutzmechanismen aus, die den Job blockieren.
Warum CAPTCHAs die Anzeigenverifizierung ausbremsen
Verifizierungs-Anbieter arbeiten breit gestreut über viele Publisher hinweg, oft über rotierende Proxys und Headless-Browser. Für die Schutzsysteme der Zielseiten sieht dieses Verhalten wie Scraping oder ein Bot-Angriff aus – und genau die Signale, die eine saubere Prüfung braucht, lösen die Abfrage aus. Eine Whitelist pro Publisher pflegen Sie bei mehreren hundert Domains nicht mehr von Hand. Die folgende Tabelle zeigt, welche Prüfpunkte betroffen sind und warum.
| Prüfpunkt | Beschreibung | Warum CAPTCHAs blockieren |
|---|---|---|
| Anzeigenplatzierung | Erscheint die Anzeige im sichtbaren Bereich (above the fold)? | Automatisierte Seitenaufrufe lösen die Bot-Erkennung aus |
| Markensicherheit | Keine Anzeigen neben schädlichen Inhalten | Massenhafte URL-Prüfung ähnelt Scraping |
| Sichtbarkeit (Viewability) | War die Anzeige tatsächlich sichtbar? | Cloudflare markiert Headless-Browser |
| Geo-Targeting | Richtige Anzeige in der richtigen Region | Proxy-Traffic löst CAPTCHAs aus |
| Konkurrenzbeobachtung | Welche Anzeigen schalten Wettbewerber? | Anzeigenabfragen mit hohem Volumen |
Die Verifizierungs-Pipeline mit CaptchaAI umsetzen
Der Ablauf ist bei jeder geschützten Seite gleich: Seite abrufen, prüfen ob ein sitekey im HTML steht, die Abfrage an CaptchaAI übergeben, das Token abwarten und mit dem Formular zurücksenden. Auf Publisher-Seiten ist reCAPTCHA v2 (Methode userrecaptcha) der häufigste Typ, meist auf Consent-Walls oder Login-Bereichen. Erst nach dem Lösen kommen Sie an das gerenderte HTML mit den Anzeigen-Tags.
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)
Das Ergebnis pro URL landet strukturiert in verification_report.json: erkannte Anzeigen-Tags, Markensicherheits-Flag und ob eine Abfrage gelöst werden musste. Diesen Report können Sie direkt in Ihr Reporting oder ein Dashboard einspeisen.
Cloudflare-geschützte Premium-Publisher abdecken
Ein großer Teil der reichweitenstarken Publisher – gerade im DACH-Raum bei etablierten Nachrichten- und Fachportalen – sitzt hinter Cloudflare. Hier begegnen Ihnen zwei Varianten: die leichtgewichtige Cloudflare-Turnstile-Abfrage (Methode turnstile, Token-Feld cf-turnstile-response) und die vollständige Cloudflare Challenge, bei der die Solve-Anfrage denselben Proxy nutzen muss wie der spätere Seitenaufruf. Beide Typen unterstützt CaptchaAI regulä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 cf_clearance and use same proxy
return data
return resp
Wichtig bei der vollständigen Challenge: Das zurückgegebene cf_clearance-Cookie ist an die IP der Solve-Session gebunden. Verwenden Sie für den anschließenden Seitenabruf denselben Proxy, sonst verwirft Cloudflare die Sitzung.
Durchsatz und Kosten über Threads planen
CaptchaAI rechnet pro gleichzeitigem Thread ab, nicht pro Lösung – jeder Thread umfasst unbegrenzte Lösungen im Abrechnungsmonat, ohne Aufpreis je CAPTCHA-Typ. Für die Anzeigenverifizierung heißt das: Ihre Parallelität ist an die Thread-Zahl gebunden. Ein Thread verarbeitet eine laufende Abfrage; sobald sie fertig ist, nimmt er die nächste URL. Wer nachts einige tausend Publisher-Seiten prüft, skaliert schlicht über mehr Threads.
Für kleine, regelmäßige Läufe reicht BASIC (15 $/Monat, 5 Threads). Größere Kampagnen fahren Sie mit ADVANCE (90 $/Monat, 50 Threads) oder PREMIUM (170 $/Monat, 100 Threads). Die Preise sind in US-Dollar. Die Verifizierungs-Worker selbst laufen kostengünstig auf gängiger DACH-Infrastruktur wie Hetzner oder IONOS – die Solving-Kapazität liefert die API.
DSGVO und rechtliche Sorgfalt im DACH-Raum
Anzeigenverifizierung im großen Maßstab berührt zwei Themen, die im deutschsprachigen Raum ernst genommen werden. Erstens der Datenschutz: Sobald Sie über Residential-Proxys arbeiten, sind IP-Adressen im Spiel, die nach DSGVO als personenbezogene Daten gelten. Prüfen Sie Ihre Datenflüsse und die Rechtsgrundlage, bevor eine Kampagne live geht – das ist Sorgfaltspflicht auf Ihrer Seite, keine Compliance-Zusage von CaptchaAI. Zweitens die Konkurrenzbeobachtung: Wer Wettbewerberanzeigen erfasst und daraus vergleichende Aussagen ableitet, sollte diese nach UWG § 6 sachlich und nachprüfbar halten. Konservative, belegbare Angaben schaffen bei DACH-Lesern mehr Vertrauen als jede Superlativ-Behauptung.
Häufige Fragen
Welche CAPTCHA-Typen treten bei der Anzeigenverifizierung am häufigsten auf?
Überwiegend reCAPTCHA v2 und v3 sowie Cloudflare Turnstile und Cloudflare Challenge auf premium-geschützten Publishern. Alle vier löst CaptchaAI regulär; dazu kommen bei Bedarf Bild- und Grid-CAPTCHAs sowie GeeTest v3.
Wie viele Threads brauche ich für eine große Verifizierungskampagne?
Das hängt von der gewünschten Parallelität ab. Als grobe Orientierung schaffen Sie je nach CAPTCHA-Häufigkeit und Lösungszeit etwa 200–500 Seiten pro Stunde und Thread-Bündel; für nächtliche Läufe über tausende URLs sind 50–100 Threads (ADVANCE oder PREMIUM) ein guter Startpunkt.
Ist die automatisierte Anzeigenprüfung DSGVO-konform?
Das liegt in Ihrer Verantwortung, nicht in der des Solving-Dienstes. Dokumentieren Sie die Rechtsgrundlage für die Verarbeitung, insbesondere bei Proxy-gebundenen IP-Adressen, und beschränken Sie die Prüfung auf zulässige, öffentlich erreichbare Publisher-Inhalte.
Kann ich Video-Anzeigen genauso prüfen?
Für Display- und native Anzeigen genügt der HTTP-basierte Ansatz oben. Video-Anzeigen brauchen in der Regel echtes Browser-Rendering mit Selenium oder Playwright – CaptchaAI löst dabei die Abfrage, das Rendering übernimmt der Browser.