A verificação de anúncios exige a visita a milhares de páginas da web para verificar o posicionamento do anúncio, a segurança da marca e a conformidade. Muitos sites de editores usam CAPTCHAs que bloqueiam verificações automatizadas. CaptchaAI mantém seu pipeline de verificação em execução.
O que a verificação de anúncios verifica
| Verifique | Descrição | Por que os CAPTCHAs bloqueiam |
|---|---|---|
| Posicionamento do anúncio | O anúncio é exibido acima da dobra? | Visitas automatizadas à página acionam detecção de bot |
| Segurança da marca | Nenhum anúncio próximo a conteúdo prejudicial | A verificação de URL em massa se assemelha à raspagem |
| Visibilidade | O anúncio estava realmente visível? | Navegadores headless sinalizados pela Cloudflare |
| Segmentação geográfica | Anúncio certo na região certa | O tráfego proxy aciona CAPTCHAs |
| Monitoramento do concorrente | Quais anúncios os concorrentes mostram? | Pesquisas de anúncios de alto volume |
Implementação
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)
Dimensionamento com editores protegidos pela Cloudflare
Muitos editores premium usam Cloudflare. Lide com catraca e desafios completos:
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("turnstile_staging", {
"pageurl": url,
"proxy": "user:pass@proxy:port",
"proxytype": "HTTP",
})
# Parse cookie_qa_validacao and use same proxy
return data
return resp
Perguntas frequentes
Quantas páginas posso verificar por hora?
Com CaptchaAI, você pode verificar de 200 a 500 páginas por hora dependendo da frequência do CAPTCHA e do tempo de resolução.
Isso funciona para verificação de anúncios em vídeo?
Essa abordagem funciona para anúncios gráficos e nativos. A verificação de anúncios em vídeo normalmente requer renderização no navegador com Selenium ou Playwright.
Como lidar com diferentes regiões?
Use proxies de regiões geográficas alvo. CaptchaAI oferece suporte a parâmetros de proxy para que o contexto de resolução corresponda à sua segmentação geográfica.
Guias Relacionados
- Raspagem de sites protegidos
- Práticas recomendadas de configuração de proxy
- Problemas de CAPTCHA do navegador modo headless