Cómo construir un rastreador de posiciones con la API de Búsqueda de Google en Python
Web Data Collection Specialist
TL;DR:
- Un rastreador de posiciones es un pipeline de series temporales, no una solicitud SERP. Debe preservar consulta, ubicación, idioma, dispositivo, dominio de búsqueda, tiempo de observación, URL de clasificación y posición.
- Usa una API de búsqueda cuando necesites observaciones SERP en crudo. Usa una plataforma SEO completa cuando también necesites descubrimiento de palabras clave, informes, alertas y flujos de trabajo para clientes.
- Normaliza nombres de host antes de hacer coincidir un dominio objetivo. Trata
www.example.com, diferencias de esquema, rutas y subdominios de acuerdo con una política explícita. - Registra "no clasificado" como dato. No conviertas la ausencia en posición cero, y no lleves la posición de ayer hacia adelante.
- Almacena la URL de clasificación así como el rango. Un dominio puede mantener su posición mientras la página de destino cambia.
- La API de búsqueda de Google sin scraping devuelve datos de búsqueda estructurados. La implementación de Python a continuación solicita SERPs, analiza resultados orgánicos y escribe instantáneas CSV de sólo adición.
Lo que un Rastreador de Posiciones Realmente Mide
Un rastreador de posiciones observa dónde aparece un dominio objetivo en un conjunto específico de resultados de búsqueda en un momento específico.
Esa definición es deliberadamente estrecha. La posición es condicional a la consulta, país o ubicación, idioma, dominio de Google, dispositivo, tipo de resultado y profundidad de paginación. Cambia una dimensión y la observación pertenece a una serie diferente.
Un registro confiable debe contener al menos:
- palabra clave
- dominio objetivo
- posición observada o un estado explícito de no clasificado
- URL de clasificación
- título del resultado
- configuración de país o ubicación
- idioma
- dispositivo
- dominio de Google
- sello de tiempo de observación
El rastreador nunca debe implicar que una SERP muestreada es un rango universal. La personalización, los experimentos, los cambios de índice y las diferencias regionales son parte de la búsqueda.
API de Búsqueda vs Plataforma de Rastreo de Posiciones
Una API de búsqueda y una plataforma de rastreo de posiciones resuelven trabajos relacionados pero diferentes.
| Necesidad | API de búsqueda | Plataforma de rastreo de posiciones |
|---|---|---|
| Registros de resultados orgánicos en crudo | Encaje fuerte | Usualmente disponible a través del modelo de plataforma |
| Lógica de coincidencia personalizada | Control total | Depende de la plataforma |
| Base de datos y panel propios | Tú lo construyes | A menudo incluido |
| Descubrimiento de palabras clave | Flujo de trabajo separado | A menudo incluido |
| Informes de etiqueta blanca | Tú los construyes | A menudo incluido |
| Programa de muestreo inusual | Control total | Dependiente del plan |
| Integración con datos internos | Directo | Exportación o dependiente de API |
Elige una API cuando las observaciones de rango sean una entrada para un producto interno, experimento o almacén de datos. Elige una plataforma cuando los analistas necesiten una interfaz lista para usar y un flujo de trabajo de informes.
Modelo de Solicitud de API de Búsqueda de Google
API de Búsqueda de Google sin scraping acepta parámetros de búsqueda y devuelve datos estructurados. La actual documentación de la API de búsqueda de Google documenta parámetros comunes, incluidos consulta, país, idioma, dominio de Google, tipo de resultado, desplazamiento y conteo de resultados.
Usa el nombre actual orientado al cliente, API de Búsqueda de Google, en la copia del producto. Los nombres de actores estables y las rutas de API pueden conservar una nomenclatura interna más antigua.
La solicitud utilizada por esta guía es un POST a /api/v1/scraper/request con actor scraper.google.search. La autenticación pertenece al encabezado x-api-token. La entrada mantiene la consulta y la configuración de búsqueda juntas para que cada respuesta pueda ser rastreada hasta su configuración de muestreo.
Construye el Rastreador en Python
El script a continuación realiza cuatro trabajos:
- envía una solicitud de API de Búsqueda de Google por cada palabra clave;
- encuentra el primer resultado orgánico cuyo nombre de host coincide con la política objetivo;
- escribe una instantánea CSV de sólo adición;
- preserva una posición y URL en blanco cuando no se encuentra el objetivo.
Requisito previo: la solicitud en vivo requiere una clave API de Scrapeless en
SCRAPELESS_API_KEY. La lógica de coincidencia, normalización y CSV puede ser probada localmente con un fixture de respuesta guardado antes de realizar una solicitud autenticada.
python
import csv
import os
from datetime import datetime, timezone
from pathlib import Path
from urllib.parse import urlparse, urlunsplit
import requests
API_URL = "https://api.scrapeless.com/api/v1/scraper/request"
def normalized_host(value: str) -> str:
candidate = value if "://" in value else urlunsplit(("https", value, "", "", ""))
host = (urlparse(candidate).hostname or "").lower().rstrip(".")
return host.removeprefix("www.")
def host_matches(result_url: str, target_domain: str, include_subdomains=True) -> bool:
result_host = normalized_host(result_url)
target_host = normalized_host(target_domain)
if not result_host or not target_host:
return False
return result_host == target_host or (
include_subdomains and result_host.endswith(f".{target_host}")
)
def organic_results(payload: dict) -> list[dict]:
if isinstance(payload.get("organic_results"), list):
return payload["organic_results"]
data = payload.get("data", {})
if isinstance(data, dict) and isinstance(data.get("organic_results"), list):
return data["organic_results"]
return []
def find_rank(payload: dict, target_domain: str) -> dict:
for fallback_position, item in enumerate(organic_results(payload), start=1):
url = item.get("link") or item.get("url") or ""
if host_matches(url, target_domain):
return {
"position": item.get("position", fallback_position),
"ranking_url": url,
"title": item.get("title", ""),
}
return {"position": None, "ranking_url": "", "title": ""}
def fetch_serp(keyword: str, *, gl="us", hl="en", device="desktop") -> dict:
api_key = os.environ["SCRAPELESS_API_KEY"]
response = requests.post(
API_URL,
headers={"x-api-token": api_key, "Content-Type": "application/json"},
json={
"actor": "scraper.google.search",
"input": {
"q": keyword,
"gl": gl,
"hl": hl,
"google_domain": "google.com",
"device": device,
"start": 0,
},
},
timeout=60,
)
response.raise_for_status()
return response.json()
def append_snapshot(path: Path, row: dict) -> None:
fields = [
"observed_at", "keyword", "target_domain", "position",
"ranking_url", "title", "gl", "hl", "device", "google_domain",
]
exists = path.exists()
with path.open("a", newline="", encoding="utf-8") as handle:
writer = csv.DictWriter(handle, fieldnames=fields)
if not exists:
writer.writeheader()
writer.writerow(row)
def track(keyword: str, target_domain: str, output="rank_history.csv") -> dict:
settings = {"gl": "us", "hl": "en", "device": "desktop"}
payload = fetch_serp(keyword, **settings)
match = find_rank(payload, target_domain)
row = {
"observed_at": datetime.now(timezone.utc).isoformat(),
"keyword": keyword,
"target_domain": normalized_host(target_domain),
"position": match["position"] or "",
"ranking_url": match["ranking_url"],
"title": match["title"],
**settings,
"google_domain": "google.com",
}
append_snapshot(Path(output), row)
return row
if __name__ == "__main__":
print(track("web scraping api", "scrapeless.com"))
La documentación de urlparse de la biblioteca estándar explica por qué el análisis de nombres de host debería usar un analizador de URL en lugar de un corte de cadena. El script elimina solo un www. líder y opcionalmente acepta subdominios; ajusta esa política antes de rastrear un patrimonio de dominio multi-marca.
Valida el Analizador de Posiciones
Antes de usar créditos en vivo, guarda una respuesta API real de la cuenta y ejecuta el analizador contra ella. Incluye al menos estos fixtures:
| Fixture | Resultado esperado |
|---|---|
| Dominio raíz exacto | Coincidido |
versión de www. |
Coincidido |
| Subdominio permitido | Coincidido |
Dominio similar como example.com.attacker.test |
No coincido |
| URL de resultado mal formada o faltante | No coincido |
| Objetivo ausente de las páginas muestreadas | La posición está en blanco; el estado no está clasificado |
No calcule una posición a partir del orden de la lista cuando la API suministre un campo position explícito sin antes entender la paginación. En una página de resultados posterior, el índice de la lista uno no es la posición global uno. Preserve la posición suministrada o añada deliberadamente el desfase de página.
Almacenar el Historial Sin Reescribirlo
Las instantáneas de solo anexar son más fáciles de auditar que una tabla de “rango actual” mutable. Una transformación posterior puede seleccionar la fila más nueva por palabra clave y mercado.
CSV funciona para un rastreador personal. Un servicio de producción debe usar una clave de base de datos que distinga la palabra clave, dominio, país o ubicación, idioma, dispositivo, dominio de Google y tiempo de observación. La documentación de tablas SQLite es suficiente para un servicio local compacto; un almacén se vuelve útil cuando la serie alimenta paneles y alertas. Para reglas de identidad de URL más allá de la política de nombre de host utilizada aquí, consulte el estándar de sintaxis genérica de URI.
Mantenga tanto position como ranking_url. Estos cambios significan cosas diferentes:
- cambios de posición, URL sin cambios: la misma página de destino se movió;
- posición sin cambios, URL cambia: Google seleccionó una página diferente;
- posición en blanco: el dominio no se encontró dentro de la profundidad de resultados muestreados;
- aparecen varias URL del dominio: almacene la mejor posición y opcionalmente retenga cada coincidencia en una tabla de detalles.
Manejar Geografía, Idioma, Dispositivo y Tiempo
Trate los ajustes de búsqueda como dimensiones, no como etiquetas opcionales añadidas más tarde.
glindica un contexto de país.hlcontrola el idioma de la interfaz.google_domainselecciona la propiedad de Google.devicesepara las observaciones de escritorio y móvil cuando se admite.- un ajuste de ubicación precisa puede modelar un mercado más estrechamente que un país.
- la marca de tiempo debe utilizar UTC en el almacenamiento y convertir solo para mostrar.
No mezcle una serie a nivel de ciudad con una serie a nivel de país bajo la misma línea de gráfico. De igual manera, un resultado móvil no debe reemplazar silenciosamente una observación de escritorio.
El tiempo de muestreo también importa. Ejecute grupos de palabras clave comparables en una ventana limitada. Si un lote se extiende durante muchas horas, almacene la marca de tiempo de cada solicitud en lugar de una fecha para todo el trabajo.
Calcular el Costo Sin Publicar un Precio Rancio
El cálculo estable es más útil que un monto de plan copiado:
monthly requests = keywords × markets × devices × pages sampled × runs per month
Luego aplique la tarifa actual de la cuenta y la política de manejo de fallas. Separe las solicitudes planificadas de los intentos repetidos y fallidos para que un equipo de operaciones pueda explicar la factura. Verifique precios de Scrapeless en el momento de la implementación en lugar de incrustar un número que puede envejecer antes que el código.
Comience a Raspar con Scrapeless
¡Potencie su raspado web y flujo de trabajo de automatización con Scrapeless!
Regístrese hoy y obtenga $5 en crédito gratuito — sin tarjeta de crédito requerida.Reclame su crédito gratuito ahora en el Tablero de Scrapeless.
Lista de Verificación de Producción
- Fije un contrato de esquema para los campos que consume el analizador.
- Mantenga la clave de API en un administrador de secretos o variable de entorno.
- Repita solo solicitudes limitadas después de fallos temporales del servicio; no haga bucles indefinidamente.
- Almacene los ajustes de solicitud junto a cada observación.
- Distinguir no clasificado de solicitud fallida.
- Rastree la URL de clasificación, no solo la posición numérica.
- Preserve un fixture de respuesta redactada para pruebas de regresión del analizador.
- Respete los términos aplicables, requisitos de privacidad y leyes locales.
- Alerta sobre lotes faltantes y deriva del esquema antes de alertar sobre movimientos de SEO.
Conclusión
Un rastreador de rangos útil es un sistema de observación disciplinado. La API de Google Search de Scrapeless proporciona registros SERP estructurados; el valor proviene de coincidencias explícitas, dimensiones de búsqueda completas, historial de solo anexar y un tratamiento honesto de los resultados ausentes.
Comience con una palabra clave, un mercado, un dispositivo y un fixture verificado. Una vez que la serie sea estable, amplíe el lote y conecte el CSV o base de datos a un panel. Para flujos de trabajo adyacentes, consulte la guía de la API de Google Search.
Construya Su Primera Instantánea SERP
Únase a la comunidad de Scrapeless para obtener ayuda con la implementación y patrones de tuberías de datos: Discord · Telegram.
Crea una cuenta gratuita en app.scrapeless.com, ejecuta una consulta acotada y valida la respuesta guardada antes de programar el rastreador.
FAQ
P: ¿Qué es una API de rastreo de posiciones?
Una API de rastreo de posiciones proporciona observaciones de resultados de búsqueda o posiciones que el software puede almacenar y analizar. Una API SERP devuelve registros de resultados en bruto; una API de rastreo de posiciones dedicada también puede proporcionar proyectos, historial, alertas e informes.
P: ¿Cómo encuentro la posición de mi dominio en los resultados orgánicos?
Analiza cada URL de resultado orgánico con un analizador de URL, normaliza el nombre de host, aplica una política explícita de apex/subdominio y devuelve la posición proporcionada del primer resultado coincidente. Evita la coincidencia de subcadenas.
P: ¿Qué posición debo guardar cuando falta el dominio?
Guarda una posición nula o en blanco más un estado explícito de no clasificado para la profundidad muestreada. No utilices cero y no lleves adelante la observación anterior.
P: ¿Con qué frecuencia debe ejecutarse un rastreador de posiciones?
Elige una cadencia basada en la decisión que los datos apoyan. El muestreo diario es común para el monitoreo activo de SEO, mientras que los informes estratégicos más lentos pueden necesitar menos. La consistencia y configuraciones comparables importan más que la frecuencia máxima.
P: ¿Este script prueba un ranking universal en Google?
No. Registra una observación estructurada para una consulta definida, mercado, idioma, dispositivo, dominio, profundidad y configuraciones de tiempo. Los resultados de búsqueda pueden variar fuera de esa configuración de muestreo.
En Scrapeless, solo accedemos a datos disponibles públicamente y cumplimos estrictamente con las leyes, regulaciones y políticas de privacidad del sitio web aplicables. El contenido de este blog es sólo para fines de demostración y no implica ninguna actividad ilegal o infractora. No ofrecemos garantías y renunciamos a toda responsabilidad por el uso de la información de este blog o enlaces de terceros. Antes de realizar cualquier actividad de scraping, consulte a su asesor legal y revise los términos de servicio del sitio web de destino u obtenga los permisos necesarios.


