Files
fn_registry/python/functions/datascience/scrape_google_trends.md
T
egutierrez e1e9bb7499 feat(shell): auto-commit con 31 cambios
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-14 23:55:16 +02:00

5.4 KiB

name, kind, lang, domain, version, purity, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, params, output, tested, tests, test_file_path, file_path
name kind lang domain version purity signature description tags uses_functions uses_types returns returns_optional error_type imports params output tested tests test_file_path file_path
scrape_google_trends function py datascience 1.0.0 impure def scrape_google_trends(keywords: list[str], geo: str = "ES", timeframe: str = "now 7-d", include_related: bool = True) -> list[dict] Capta interes de busqueda de Google Trends por keyword/nicho via pytrends. El interes es relativo 0-100, NUNCA volumen absoluto. Aplana interest_over_time + related_queries (rising/top) en filas con schema fijo que casa 1:1 con la tabla Postgres google_trends. Backoff/retry ante 429.
google-trends
pytrends
trends
market-intel
datascience
false error_go_core
pytrends
time
name desc
keywords lista de terminos/nichos a consultar (max 5 por payload, limite de Google Trends). Cada elemento es una keyword string.
name desc
geo codigo de pais ISO-3166 (ej. 'ES', 'US', '' para mundial). Default 'ES'.
name desc
timeframe ventana temporal en sintaxis pytrends (ej. 'now 7-d', 'today 3-m', 'today 12-m', '2024-01-01 2024-12-31'). Default 'now 7-d'.
name desc
include_related si True anade filas metric='rising' y metric='top' de related_queries por keyword. Si False solo interest_over_time. Default True.
lista de dicts con claves EXACTAS {geo, timeframe, keyword, metric, point_date, value, related_query}. Tres tipos de fila segun metric: 'interest_over_time' (point_date=fecha ISO, value=0-100, related_query=None), 'rising' (related_query=query, value=valor rising o BREAKOUT_SENTINEL, point_date=None), 'top' (related_query=query, value=0-100, point_date=None). No incluye id/snapshot_date/scraped_at (los anade el ingest). false
python/functions/datascience/scrape_google_trends.py

Ejemplo

import sys, os
sys.path.insert(0, os.path.join("python", "functions"))
from datascience.scrape_google_trends import scrape_google_trends

# Interes de busqueda en Espana, ultimos 7 dias, con related queries
rows = scrape_google_trends(
    ["coche electrico", "panel solar"],
    geo="ES",
    timeframe="now 7-d",
    include_related=True,
)

# Cada fila tiene el mismo schema, listo para insertar en Postgres google_trends:
# {"geo": "ES", "timeframe": "now 7-d", "keyword": "coche electrico",
#  "metric": "interest_over_time", "point_date": "2026-06-12", "value": 73,
#  "related_query": None}
#
# {"geo": "ES", "timeframe": "now 7-d", "keyword": "coche electrico",
#  "metric": "rising", "point_date": None, "value": 999999,   # "Breakout"
#  "related_query": "ayudas coche electrico 2026"}
#
# {"geo": "ES", "timeframe": "now 7-d", "keyword": "panel solar",
#  "metric": "top", "point_date": None, "value": 100,
#  "related_query": "placas solares precio"}

interes = [r for r in rows if r["metric"] == "interest_over_time"]
print(len(interes), "puntos de interes temporal")

Cuando usarla

Cuando necesites medir el interes/momentum de un nicho o keyword en el tiempo (market intelligence, deteccion de tendencias, validacion de demanda de producto) y vayas a persistirlo en la tabla Postgres google_trends. Usala antes del ingest: devuelve filas crudas con el schema exacto de la tabla, sin los campos que pone el ingest (id, snapshot_date, scraped_at). Pon include_related=False si solo te interesa la serie temporal y quieres minimizar la superficie de rate-limit.

Gotchas

  • API no oficial + rate-limit (429). pytrends scrapea una API interna de Google que NO es publica. Google la limita agresivamente: rafagas de llamadas devuelven HTTP 429. La funcion reintenta con backoff incremental (5s, 15s, 30s) ante 429; si tras esos reintentos sigue limitada, lanza RuntimeError mencionando explicitamente el rate-limit. En entornos de CI/headless es habitual recibir 429 a la primera — no es un bug de la funcion.
  • Puede romperse sin aviso. Al depender de un endpoint interno, Google puede cambiarlo y romper pytrends en cualquier momento. Trata los fallos como esperados y cachea resultados aguas arriba.
  • Interes relativo, NO volumen absoluto. Los valores 0-100 estan normalizados DENTRO del payload consultado (mismo geo + timeframe + conjunto de keywords). 100 = el pico del conjunto, no "100 busquedas". No son comparables entre payloads distintos. Cambiar el set de keywords reescala todos los valores.
  • "Breakout" en rising. Google marca como la cadena literal "Breakout" (en vez de un %) las related_queries rising cuyo crecimiento supera ~5000%. Para mantener la columna value numerica en Postgres se mapea al sentinel BREAKOUT_SENTINEL = 999999. Si necesitas distinguir un breakout real de un valor 999999 legitimo (imposible en la practica para %), filtra por ese sentinel.
  • Maximo 5 keywords por payload. Limite de Google Trends. Pasar mas keywords hace que pytrends falle o ignore las extra. Trocea en lotes de <=5 y llama varias veces (espaciando para no disparar el 429).
  • DataFrames vacios. interest_over_time() puede volver vacio (keyword sin datos en la ventana) y related_queries() devuelve un dict {keyword: {'top': df|None, 'rising': df|None}} con valores None. La funcion maneja ambos casos sin petar: simplemente no genera filas para esas combinaciones.
  • Columna isPartial. interest_over_time() incluye una columna isPartial que marca el ultimo punto como provisional. Se ignora por completo (solo se leen las columnas que coinciden con las keywords).