763e06c127
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4.6 KiB
4.6 KiB
Capability: seo
SEO orientado a datos sobre Google Search Console (GSC): autenticar contra la Search Console
API con una cuenta de servicio, extraer Search Analytics (impresiones, clicks, CTR, posición
por query y página) y aterrizarlo en DuckDB (verdad acumulada) + Postgres (espejo para
Metabase). Es la cadena de ingesta del proyecto seo_analytics.
La tesis del grupo: el SEO deja de hacerse a ciegas y se convierte en un problema de datos con loop medible — el dashboard señala la oportunidad (striking distance, CTR bajo, content decay), se aplica el cambio y se mide el impacto en la siguiente ingesta.
Funciones
| ID | Firma | Qué hace |
|---|---|---|
gsc_auth_py_infra |
gsc_auth(credentials_path="", subject="") -> service |
Autentica contra la Search Console API v1 con una service account JSON (scope webmasters.readonly). Fallback a env GSC_SA_JSON. Devuelve el service de googleapiclient listo para consultar. |
pull_gsc_search_analytics_py_datascience |
pull_gsc_search_analytics(service, site_url, start_date, end_date, dimensions=None, row_limit=25000, max_total_rows=0, search_type="web") -> list[dict] |
Extrae Search Analytics paginando (startRow) hasta agotar. Aplana cada fila (keys → nombres de dimensión + clicks/impressions/ctr/position). dimensions por defecto ["query","page"]. |
ingest_gsc_search_analytics_py_pipelines |
ingest_gsc_search_analytics(site_url="", duckdb_path="", pg_dsn="", start_date="", end_date="", lookback_days=5, credentials_path="") -> dict |
Pipeline: auth → pull (dims date,query,page) → upsert idempotente en DuckDB → espejo a Postgres (mode=replace). Resuelve defaults de env (GSC_SITE_URL, SEO_DSN, GSC_SA_JSON). Lo invoca el DAG seo-gsc-daily. |
Ejemplo canónico (end-to-end)
# Greenfield: ver projects/seo_analytics/docs/SETUP.md para crear la service account,
# verificar la propiedad en Search Console y darle acceso a la SA.
# 1. Variables (el .env del proyecto las agrupa)
export GSC_SITE_URL="sc-domain:ejemplo.com"
export SEO_DSN="postgresql://captacion:PASS@localhost:5433/seo"
export GSC_SA_JSON="$HOME/.config/seo/gsc-sa.json"
# 2. Ingesta diaria (auth + pull + DuckDB + espejo Postgres) — la corre el DAG seo-gsc-daily
python/.venv/bin/python3 python/functions/pipelines/ingest_gsc_search_analytics.py
# 3. Dashboards en Metabase (una vez): añade la DB seo + 4 cards + dashboard
SEO_PG_PASS=... METABASE_USER=... METABASE_PASS=... \
python/.venv/bin/python3 projects/seo_analytics/setup_metabase.py
Uso desde Python, componiendo las tres:
import sys; sys.path.insert(0, "python/functions")
from infra import gsc_auth
from datascience import pull_gsc_search_analytics
svc = gsc_auth() # lee GSC_SA_JSON
rows = pull_gsc_search_analytics(svc, "sc-domain:ejemplo.com",
"2026-05-01", "2026-05-28",
dimensions=["date", "query", "page"])
print(len(rows), rows[0])
Fronteras
- NO hace keyword research ni rank tracking externo. GSC dice por qué keywords ya apareces en Google; descubrir keywords nuevas o medir SERP de competidores es otro trabajo (scrapers).
- NO escribe los dashboards. Las cards/dashboard de Metabase los construye el script del
proyecto
setup_metabase.pycomponiendo el grupometabase. Este grupo solo ingiere datos. - NO gestiona el scheduling. Eso es
dag_engine(DAGseo-gsc-daily, gruposcheduler). - NO cubre Bing/otros buscadores. Solo Google Search Console.
Gotchas del grupo
- Los datos de GSC llegan con ~2-3 días de lag. El pipeline pide hasta hoy menos 3 días.
- Google anonimiza queries de baja frecuencia (privacy threshold): la suma por query no cuadra con el total del sitio. Es esperado, no un bug.
- El formato de
site_urlimporta:sc-domain:ejemplo.com(propiedad de dominio) vs URL completa con esquema (propiedad de prefijo). - La service account accede porque su email está añadido como usuario en Search Console (Settings > Users), no por domain-wide delegation. El JSON de la SA es un secreto.
- DuckDB es la verdad (upsert idempotente, acumula histórico); Postgres es un espejo
que se regenera por
replaceen cada sync. No acumular en Postgres directamente.
Prerequisitos
- Sitio verificado en Search Console + service account con acceso (ver SETUP.md del proyecto).
- Stack Postgres + Metabase del proyecto
captacion_clientes(contenedorescaptacion-postgres:5433 ycaptacion-metabase:3030), con la DBseocreada. - Deps Python
google-api-python-client+google-auth(ya en el venv del registry).