
Aloísio Vítor
Image Processing Expert

Google's AI Overviews now appear for a growing percentage of search queries, citing specific web pages as sources. For brands and publishers, being cited in these AI-generated summaries drives significant traffic and authority. Monitoring which pages get cited — and when citations change — requires automated data collection from Google's search results. This guide shows how to build an AI Overview citation monitoring system using CapSolver to handle Google's verification challenges and maintain continuous tracking.
Google AI Overviews represent a fundamental shift in how search traffic flows. When Google generates an AI-powered answer and cites your page, you receive both a direct link and implied authority. When your citation disappears, traffic from that query drops immediately. Search Engine Land research indicates that AI Overviews now appear on 15-30% of informational queries, with the percentage growing monthly.
The challenge for monitoring is that AI Overview citations are dynamic — they change based on content freshness, query reformulation, and Google's ongoing model updates. A page cited today may lose its citation tomorrow without any notification. Manual checking is impractical at scale: a brand tracking 200 keywords would need to manually search each one, scroll to the AI Overview, and record which sources are cited — multiple times per week.
Automated monitoring solves this, but Google's bot protection blocks systematic search access. After 50-100 automated queries, Google presents a reCAPTCHA challenge or blocks the IP entirely. CapSolver provides the verification-clearing layer that keeps your monitoring pipeline running continuously.
Install required packages:
pip install git+https://github.com/capsolver-ai/capsolver-core.git
pip install aiohttp beautifulsoup4 pandas
Set your API key:
export CAPSOLVER_API_KEY="your-capsolver-api-key"
Additional requirements:
Not all queries generate AI Overviews. Focus your monitoring on keywords where AI Overviews consistently appear:
from dataclasses import dataclass, field
from typing import List, Optional
import time
@dataclass
class AIOverviewCitation:
"""A single citation within an AI Overview."""
position: int # 1-based position in the citation list
url: str # Cited page URL
domain: str # Domain of the cited page
anchor_text: str # Text used to link to the source
snippet_context: str # Surrounding text in the AI Overview
@dataclass
class AIOverviewResult:
"""Complete AI Overview monitoring result for one keyword."""
keyword: str
has_ai_overview: bool
citations: List[AIOverviewCitation] = field(default_factory=list)
overview_text: str = ""
timestamp: float = 0.0
your_domain_cited: bool = False
your_citation_position: Optional[int] = None
# Keywords most likely to trigger AI Overviews
PRIORITY_KEYWORDS = [
# Informational queries (highest AI Overview rate)
"what is generative engine optimization",
"how to optimize for AI search",
"best practices for AI citation",
# Commercial investigation queries
"best CAPTCHA solving API",
"top AI agent frameworks 2025",
# Comparison queries
"reCAPTCHA vs Cloudflare Turnstile",
]
Informational and "how to" queries have the highest AI Overview trigger rate (40-60%), followed by comparison queries (20-30%) and commercial investigation queries (15-25%).
Monitoring keywords that never trigger AI Overviews wastes CAPTCHA solving credits. Focus on queries where your content has citation potential — informational queries in your expertise area, comparison queries where your product is relevant, and "best of" queries in your category.
Create a parser that extracts AI Overview citations from Google search result pages:
from bs4 import BeautifulSoup
import re
class AIOverviewExtractor:
"""Extract AI Overview citations from Google SERP HTML."""
def extract(self, html: str, keyword: str, your_domain: str = "") -> AIOverviewResult:
"""Parse HTML and extract AI Overview citation data."""
soup = BeautifulSoup(html, 'html.parser')
# Detect AI Overview presence
# Google uses various container classes for AI Overviews
ai_containers = soup.select(
'[data-attrid*="ai"], '
'.ai-overview, '
'[class*="aiOverview"], '
'.kp-wholepage [data-md-type]'
)
if not ai_containers:
return AIOverviewResult(
keyword=keyword,
has_ai_overview=False,
timestamp=time.time()
)
# Extract the AI Overview text
overview_container = ai_containers[0]
overview_text = overview_container.get_text(separator=" ", strip=True)[:2000]
# Extract citations (source links within the AI Overview)
citations = []
source_links = overview_container.select('a[href^="http"]')
for i, link in enumerate(source_links, 1):
url = link.get('href', '')
if not url or 'google.com' in url:
continue
domain = self._extract_domain(url)
anchor = link.get_text(strip=True)
# Get surrounding context
parent = link.parent
context = parent.get_text(strip=True)[:200] if parent else ""
citations.append(AIOverviewCitation(
position=i,
url=url,
domain=domain,
anchor_text=anchor,
snippet_context=context
))
# Check if your domain is cited
your_cited = any(your_domain in c.domain for c in citations) if your_domain else False
your_position = next(
(c.position for c in citations if your_domain in c.domain), None
) if your_domain else None
return AIOverviewResult(
keyword=keyword,
has_ai_overview=True,
citations=citations,
overview_text=overview_text[:500],
timestamp=time.time(),
your_domain_cited=your_cited,
your_citation_position=your_position
)
def _extract_domain(self, url: str) -> str:
"""Extract domain from URL."""
match = re.search(r'https?://([^/]+)', url)
return match.group(1) if match else url
Build the data collection layer with integrated CAPTCHA solving:
import asyncio
import aiohttp
import random
from capsolver_core import create_capsolver, CaptchaType, CaptchaInfo
class CitationMonitorCollector:
"""Collect AI Overview data with CAPTCHA handling."""
def __init__(self, api_key: str, proxies: list):
self.cap = create_capsolver(api_key=api_key)
self.proxies = proxies
self.proxy_idx = 0
self.extractor = AIOverviewExtractor()
self.stats = {"searches": 0, "captchas": 0, "overviews_found": 0}
async def collect_citation_data(
self, keyword: str, your_domain: str = "", location: str = "us"
) -> AIOverviewResult:
"""Collect AI Overview citation data for a keyword."""
proxy = self.proxies[self.proxy_idx % len(self.proxies)]
self.proxy_idx += 1
url = f"https://www.google.com/search?q={keyword}&gl={location}&hl=en"
headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36",
"Accept": "text/html,application/xhtml+xml",
"Accept-Language": "en-US,en;q=0.9"
}
async with aiohttp.ClientSession() as session:
async with session.get(url, headers=headers, proxy=proxy, timeout=30) as resp:
html = await resp.text()
# Handle CAPTCHA if triggered
if "unusual traffic" in html.lower() or "g-recaptcha" in html:
self.stats["captchas"] += 1
html = await self._solve_and_retry(session, url, headers, proxy)
self.stats["searches"] += 1
# Extract citation data
result = self.extractor.extract(html, keyword, your_domain)
if result.has_ai_overview:
self.stats["overviews_found"] += 1
return result
async def _solve_and_retry(self, session, url, headers, proxy) -> str:
"""Solve Google's reCAPTCHA and retry the search."""
info = CaptchaInfo(
type=CaptchaType.RECAPTCHA_V2,
website_url="https://www.google.com",
website_key="6LfwuyUTAAAAAOAmoS0fdqijC2PbbdH4kjq62Y1b"
)
solution = await self.cap.solve(info)
# Retry with a fresh proxy after solving
new_proxy = self.proxies[self.proxy_idx % len(self.proxies)]
self.proxy_idx += 1
async with session.get(url, headers=headers, proxy=new_proxy, timeout=30) as resp:
return await resp.text()
async def monitor_batch(
self, keywords: list, your_domain: str = "", delay: float = 7.0
) -> list:
"""Monitor a batch of keywords with rate limiting."""
results = []
for keyword in keywords:
result = await self.collect_citation_data(keyword, your_domain)
results.append(result)
await asyncio.sleep(delay + random.uniform(0, 3))
return results
async def close(self):
await self.cap.aclose()
The CapSolver reCAPTCHA documentation covers Google's specific reCAPTCHA implementation in detail.
Track citation changes over time and alert when your pages gain or lose AI Overview citations:
class CitationChangeDetector:
"""Detect changes in AI Overview citations over time."""
def __init__(self, your_domain: str):
self.your_domain = your_domain
self.history = {} # keyword -> list of AIOverviewResult
def record_and_detect(self, results: list) -> list:
"""Record new results and detect changes from previous check."""
changes = []
for result in results:
keyword = result.keyword
previous = self.history.get(keyword, [])
if previous:
last = previous[-1]
# Citation gained
if result.your_domain_cited and not last.your_domain_cited:
changes.append({
"type": "CITATION_GAINED",
"keyword": keyword,
"position": result.your_citation_position,
"timestamp": result.timestamp
})
# Citation lost
elif last.your_domain_cited and not result.your_domain_cited:
changes.append({
"type": "CITATION_LOST",
"keyword": keyword,
"previous_position": last.your_citation_position,
"timestamp": result.timestamp
})
# Position changed
elif (result.your_domain_cited and last.your_domain_cited and
result.your_citation_position != last.your_citation_position):
changes.append({
"type": "POSITION_CHANGED",
"keyword": keyword,
"old_position": last.your_citation_position,
"new_position": result.your_citation_position,
"timestamp": result.timestamp
})
# AI Overview appeared/disappeared
if result.has_ai_overview and not last.has_ai_overview:
changes.append({
"type": "AI_OVERVIEW_APPEARED",
"keyword": keyword,
"timestamp": result.timestamp
})
# Update history
if keyword not in self.history:
self.history[keyword] = []
self.history[keyword].append(result)
# Keep last 30 days of history
self.history[keyword] = self.history[keyword][-60:]
return changes
def generate_report(self) -> dict:
"""Generate a summary report of citation status."""
total_keywords = len(self.history)
cited_keywords = sum(
1 for k, h in self.history.items()
if h and h[-1].your_domain_cited
)
overview_keywords = sum(
1 for k, h in self.history.items()
if h and h[-1].has_ai_overview
)
return {
"total_keywords_monitored": total_keywords,
"keywords_with_ai_overview": overview_keywords,
"keywords_where_cited": cited_keywords,
"citation_rate": f"{cited_keywords/max(overview_keywords,1)*100:.1f}%",
"average_citation_position": self._avg_position()
}
def _avg_position(self) -> float:
positions = [
h[-1].your_citation_position
for h in self.history.values()
if h and h[-1].your_citation_position
]
return sum(positions) / len(positions) if positions else 0
Ejecutar todo el pipeline en un horario:
async def run_daily_monitoring():
"""Ejecución diaria de monitoreo de citas de AI Overview."""
collector = CitationMonitorCollector(
api_key="TU_CLAVE_DE_API_DE_CAPSOLVER",
proxies=LISTA_DE_PROXY_RESIDENCIALES
)
detector = CitationChangeDetector(your_domain="capsolver.com")
# Monitorear todas las palabras clave prioritarias
results = await collector.monitor_batch(
keywords=PRIORITY_KEYWORDS,
your_domain="capsolver.com",
delay=8.0
)
# Detectar cambios
changes = detector.record_and_detect(results)
# Informe
if changes:
print(f"\n{'='*50}")
print(f"CAMBIOS EN CITAS DETECTADOS: {len(changes)}")
for change in changes:
print(f" [{change['type']}] {change['keyword']}")
print(f"{'='*50}\n")
report = detector.generate_report()
print(f"Resumen: {report}")
await collector.close()
# Ejecutar diariamente
asyncio.run(run_daily_monitoring())
Reclama tu código de bonificación: Usa el código WEBS en Panel de control de CapSolver para obtener un 5% adicional en cada recarga. Esencial para los equipos GEO que rastrean citas de AI Overview a gran escala.
Los datos de monitoreo informan directamente tu estrategia de Optimización del Motor Generativo:
El blog de CapSolver sobre IA y automatización cubre patrones adicionales para la recolección de datos con IA. Para manejar diferentes tipos de CAPTCHA en motores de búsqueda, la página de productos de CapSolver lista todos los sistemas de verificación compatibles.
Monitorear automáticamente las citas de AI Overview requiere una capa de recolección de búsqueda consciente de CAPTCHA, un analizador de extracción de citas y un sistema de detección de cambios. CapSolver proporciona la infraestructura que elimina la necesidad de resolver CAPTCHA, permitiendo un monitoreo continuo de las vistas de AI de Google, resolviendo desafíos reCAPTCHA en 3-8 segundos para que tu estrategia GEO siempre tenga datos de citas actualizados.
Comienza con 20-50 palabras clave de alta prioridad donde esperas vistas de AI, valida la precisión de tu extracción, y luego escala a cobertura completa de palabras clave. Los datos de cambios en las citas informan directamente las decisiones de optimización de contenido: ayuda a entender qué considera citable Google para tus consultas objetivo.
Para palabras clave de alta prioridad (términos de marca, consultas de productos principales), verifica diariamente. Para monitoreo más amplio (términos de industria, consultas informativas), 2-3 veces por semana es suficiente. Las citas de AI Overview pueden cambiar en horas tras actualizaciones de contenido, por lo que una verificación más frecuente captura cambios más rápido.
Actualmente, 15-30% de las consultas informativas muestran vistas de AI, con un porcentaje en crecimiento. Las consultas "Cómo hacer", definiciones y comparaciones tienen las tasas más altas. Las consultas comerciales y transaccionales muestran vistas de AI con menos frecuencia.
La mayoría de las vistas de AI citan 3-8 fuentes, con las primeras 2-3 posiciones recibiendo la mayoría del tráfico. La posición 1 en la lista de citas recibe aproximadamente 3-5 veces más clics que la posición 5+. Monitorear tu posición de cita es tan importante como verificar si eres citado en absoluto.
Sí. Establece your_domain como el dominio de un competidor para rastrear su frecuencia de citas y posiciones. Compara tu tasa de citas con competidores para identificar brechas y oportunidades. Rastrea qué competidores aparecen constantemente para palabras clave donde tú estás ausente.
Con 200 palabras clave con retrasos de 8 segundos y aproximadamente un 10% de tasa de CAPTCHA, necesitas alrededor de 20 resoluciones de CAPTCHA por ejecución diaria. A $2-3 por 1,000 resoluciones de reCAPTCHA v2, el costo diario es aproximadamente $0.04-0.06 — menos de $2 por mes para un monitoreo completo de citas de vistas de AI.
Aprende una arquitectura de raspado web escalable en Rust con reqwest, scraper, raspado asíncrono, raspado con navegador sin cabeza, rotación de proxies y manejo de CAPTCHA conforme.

Automatiza la resolución de CAPTCHA con Nanobot y CapSolver. Utiliza Playwright para resolver reCAPTCHA y Cloudflare autónomamente.
