Resumen
Local businesses necesita to know donde they clasificar in Google Mapear Pack resultados a traves de their servicio area, no solo de one ubicacion. Este flujo de trabajo ejecuta at 6 AM diario, consultas Google for your palabras clave objetivo de un grid of geo-points a traves de your servicio area, registros your position in el local pack at cada point, computes clasificar cambios de el anterior dia, y genera un heatmap conjunto de datos showing donde you clasificar well y donde competidores dominate. Rastrear SEO local progreso con diario datos instead of mensual spot verifica.
Desencadenador
Cron programar (diario at 6 AM UTC)
Programación
Diario at 6 AM UTC
Pasos del flujo de trabajo
Define grid points
Cargar el grid of lat/lng points covering your servicio area. Cada point represents un simulated search ubicacion.
Consulta cada grid point
For cada point y palabra clave objetivo, search Google via Scavio. Extraer local pack resultados y your position.
Record positions
Almacenar el clasificar at cada grid point con marca de tiempo. Rastrear cual competidores appear above y below you.
Compute diario cambios
Comparar today's positions contra yesterday's datos. Marcar grid points donde clasificar improved o dropped.
Generar heatmap datos
Salida un JSON conjunto de datos of grid points con clasificar valores, suitable for renderizado un visual heatmap.
Implementacion en Python
import requests, os, json
from datetime import datetime
H = {"x-api-key": os.environ["SCAVIO_API_KEY"]}
BUSINESS_NAME = "Acme Plumbing"
KEYWORDS = ["plumber near me", "emergency plumber", "plumbing repair"]
# Grid points covering service area (lat, lng, label)
GRID_POINTS = [
{"label": "Downtown", "geo": "downtown Austin TX"},
{"label": "North", "geo": "north Austin TX"},
{"label": "South", "geo": "south Austin TX"},
{"label": "East", "geo": "east Austin TX"},
{"label": "West", "geo": "west Austin TX"},
]
def check_rank(keyword, geo_point):
"""Search from a geo-point and find business rank in results."""
query = f"{keyword} {geo_point['geo']}"
r = requests.post("https://api.scavio.dev/api/v1/search", headers=H,
json={"platform": "google", "query": query}, timeout=10).json()
local = r.get("local_results", r.get("organic", []))[:10]
rank = None
for i, item in enumerate(local):
title = item.get("title", "").lower()
if BUSINESS_NAME.lower() in title:
rank = i + 1
break
return {
"keyword": keyword,
"geo": geo_point["label"],
"rank": rank,
"top_3": [item.get("title", "")[:50] for item in local[:3]],
"checked_at": datetime.utcnow().isoformat()
}
heatmap_data = []
for kw in KEYWORDS:
for point in GRID_POINTS:
result = check_rank(kw, point)
heatmap_data.append(result)
rank_str = str(result["rank"]) if result["rank"] else "not found"
print(f"[{result['geo']}] {kw}: rank {rank_str}")
found = sum(1 for d in heatmap_data if d["rank"] is not None)
print(f"\nGrid checks: {len(heatmap_data)} | Found in results: {found}")Implementacion en JavaScript
const H = {"x-api-key": process.env.SCAVIO_API_KEY, "Content-Type": "application/json"};
const BUSINESS_NAME = "Acme Plumbing";
const KEYWORDS = ["plumber near me", "emergency plumber", "plumbing repair"];
const GRID_POINTS = [
{label: "Downtown", geo: "downtown Austin TX"},
{label: "North", geo: "north Austin TX"},
{label: "South", geo: "south Austin TX"},
{label: "East", geo: "east Austin TX"},
{label: "West", geo: "west Austin TX"},
];
async function checkRank(keyword, geoPoint) {
const r = await fetch("https://api.scavio.dev/api/v1/search", {
method: "POST", headers: H,
body: JSON.stringify({platform: "google", query: `${keyword} ${geoPoint.geo}`})
}).then(r => r.json());
const local = (r.local_results || r.organic || []).slice(0, 10);
let rank = null;
local.forEach((item, i) => {
if ((item.title || "").toLowerCase().includes(BUSINESS_NAME.toLowerCase())) rank = i + 1;
});
return {
keyword, geo: geoPoint.label, rank,
top3: local.slice(0, 3).map(i => (i.title || "").slice(0, 50)),
checkedAt: new Date().toISOString()
};
}
(async () => {
const heatmapData = [];
for (const kw of KEYWORDS) {
for (const point of GRID_POINTS) {
const result = await checkRank(kw, point);
heatmapData.push(result);
console.log(`[${result.geo}] ${kw}: rank ${result.rank || "not found"}`);
}
}
const found = heatmapData.filter(d => d.rank !== null).length;
console.log(`\nGrid checks: ${heatmapData.length} | Found in results: ${found}`);
})();Plataformas utilizadas
Búsqueda web con grafo de conocimiento, PAA y resúmenes de IA