Volver al blog
Guías
Andrei OgiolanLast updated on May 7, 202618 min read

Cómo buscar reseñas en Google Maps: Una guía práctica en Python

Cómo buscar reseñas en Google Maps: Una guía práctica en Python
En resumen: Para extraer reseñas de Google Maps hay tres métodos posibles: un rastreador de Selenium hecho a medida tras un proxy rotativo, una API de extracción con instrucciones de renderizado o una API estructurada de reseñas de Maps que devuelve datos JSON analizados. Esta guía repasa los tres métodos en Python con código listo para copiar y pegar, patrones de paginación, tácticas para evitar bloqueos y un paso final de limpieza que transforma las reseñas sin procesar en información realmente útil para las empresas.

Introducción

Si alguna vez has intentado averiguar cómo extraer reseñas de Google Maps en un volumen considerable, ya conoces los puntos débiles: la API oficial de Places devuelve como mucho un puñado de reseñas por lugar, JavaScript renderiza la mayor parte del listado y los enlaces de las clases CSS rotan con tanta frecuencia que pueden dejar un extractor inoperativo entre el viernes y el lunes. La buena noticia es que se puede acceder a los datos; solo hay que elegir la herramienta adecuada para el trabajo.

Esta guía está dirigida a desarrolladores de Python, analistas de datos y equipos de crecimiento que desean obtener reseñas de empresas de Google Maps para el análisis de opiniones, la investigación de la competencia, la inteligencia de ubicación o la generación de clientes potenciales. Analizaremos tres métodos en paralelo: Selenium más un proxy para un control total, una API de extracción con instrucciones de renderizado para una ruta con menos código, y una API JSON por reseña cuando se necesiten campos limpios y estructurados como review_id, iso_date_of_last_edity las respuestas de los propietarios.

Al finalizar, tendrás código funcional, una tabla comparativa para justificar el enfoque que elijas y un breve proceso para limpiar y analizar los datos recopilados. Cuando se sabe que los selectores o las cuotas subyacentes pueden variar, el artículo lo señala para que puedas planificarlo en lugar de tener que depurarlo a las 2 de la madrugada.

Cómo extraer reseñas de Google Maps: valor empresarial y qué campos puedes extraer

Las reseñas son uno de los conjuntos de datos de mayor relevancia en la web pública. Un feed limpio de reseñas de Maps te permite comparar la experiencia del cliente de un competidor, supervisar la reputación en diferentes ubicaciones, crear listas de clientes potenciales basadas en la ubicación, calcular un índice de opinión regional o entrenar un modelo de recomendación con comentarios reales de personas. Nada de eso funciona si solo dispones de promedios de estrellas, que es precisamente en lo que se quedan la mayoría de los rastreadores de listados genéricos.

Siendo realistas, los campos que se pueden extraer de Google Maps se dividen en dos niveles. En el nivel de ficha, se obtiene el nombre del lugar, la dirección, la puntuación global, el número de reseñas, la categoría, el horario, el teléfono y opciones de servicio como comer en el local o entrega a domicilio. En el nivel de reseña individual, se obtiene el texto de la reseña (el fragmento), el nombre del autor, el enlace al perfil, la puntuación por estrellas, la fecha de la reseña o la última modificación, las URL de las fotos, la respuesta del propietario (si la hay) y etiquetas temáticas como «Servicio» o «Ambiente». Conocer esta división desde el principio permite decidir si basta con el scraping a nivel de ficha o si es necesario profundizar en las reseñas individuales. Los casos de uso de investigación de mercado y monitorización de reseñas casi siempre requieren el segundo nivel.

Tres formas de extraer datos de reseñas de Maps: API oficial, scraper DIY o API de scraping

Cuando investigas cómo extraer reseñas de Google Maps, aparecen tres vías. Elegir la incorrecta es la razón más común por la que los equipos se rinden a mitad de camino, así que dedica unos minutos a esto antes de escribir código.

La API oficial de Google Places es la más limpia desde el punto de vista legal, pero está diseñada para integraciones de aplicaciones, no para análisis. Según la documentación de Google, las solicitudes de detalles de lugares solo devuelven un pequeño subconjunto limitado de las reseñas que se muestran en la interfaz de usuario de Maps, lo que la hace poco adecuada para la puntuación de sentimiento a cualquier escala. Un rastreador Selenium de creación propia, junto con un proxy residencial, te ofrece un control total y la misma vista que vería un usuario que no ha iniciado sesión, a costa de tener que ejecutar un navegador y estar pendiente de los cambios en el CSS. Una API de rastreo intermedia se encarga de la rotación de proxies, el manejo de CAPTCHAs y la renderización sin interfaz, y una API JSON por reseña, además de eso, se encarga también del análisis sintáctico.

Utilice la tabla siguiente como matriz de decisión fundamentada.

Enfoque

Tiempo de configuración

Límite de escala

Gestión anti-bot

Mantenimiento

Cuándo utilizarlo

API oficial de Google Places

Bajo

Bajo (límites de reseñas por establecimiento)

Integrado, pero con límite de cuota

Bajo

Incorporar algunas reseñas en la interfaz de usuario de tu propio producto

Selenium DIY más proxy

Medio

Medio

Manual: proxies, esperas, reintentos

Alto (desviación de CSS)

Control total, flujos personalizados, volumen moderado

API SERP

Bajo

Alto

Gestionado por el proveedor

Bajo

Tareas repetibles, rastreos programados

API JSON por revisión

Mínimo

Alto

Gestionado por el proveedor

Mínimo

Campos limpios, sin análisis sintáctico, la vía más rápida para acceder a los datos

Retos antibots exclusivos de Google Maps

Maps es más difícil de rastrear que un sitio de comercio electrónico típico, y no por las razones que la gente espera. Lo primero con lo que te topas es el muro de consentimiento de cookies, que bloquea la visualización del panel de resultados de búsqueda hasta que se descarta. Lo segundo es que Maps es una experiencia basada exclusivamente en JavaScript, por lo que un requests.get devuelve un shell casi vacío. El tercero, y el que suele bloquear los rastreadores con más frecuencia, es que el panel de listados utiliza una carga basada en el desplazamiento en lugar de URL paginadas. No hay ?page=2 puedes acceder.

Además de eso, Google ofusca y rota los nombres de las clases CSS. Los hooks como hfpxzc, MW4etd, UY7F9, y Nv2PK eran válidos en el momento de escribir este artículo, pero deben volver a verificarse antes de publicar o ejecutar, ya que cambian a menudo. Los patrones de solicitud agresivos desde una sola IP también provocan límites de frecuencia y, ocasionalmente, reCAPTCHA, por lo que un conjunto de proxies residenciales y esperas aleatorias no son opcionales una vez que se superan unas pocas consultas.

Requisitos previos: Python, Chrome, bibliotecas y una clave API

Necesitarás Python 3.10 o una versión más reciente y una instalación reciente de Chrome. La ruta de Selenium también necesita algunos paquetes. Instálalos con pip:

pip install selenium selenium-wire webdriver-manager beautifulsoup4 lxml requests

Cada uno cumple su función. Selenium controla el navegador. Selenium Wire es una pequeña extensión que expone las solicitudes HTTP subyacentes para que puedas conectar un proxy autenticado sin tener que manipular los indicadores de Chrome. Webdriver Manager gestiona el binario de ChromeDriver para que no tengas que fijar una versión específica en cada portátil. BeautifulSoup con el backend lxml analiza el HTML renderizado, y requests es suficiente para las secciones de API.

Para los métodos 2 y 3, regístrate en una cuenta de la API de SERP antes de empezar. Normalmente puedes conseguir un crédito gratuito para realizar pruebas y, a continuación, introducir la clave en los bloques de código que aparecen a continuación.

Método 1: guía paso a paso de Selenium más proxy

La respuesta clásica a cómo extraer reseñas de Google Maps es un navegador real más un proxy residencial rotativo. Esta es la opción que ofrece mayor alcance y control. Ejecutas una instancia de Chrome, rediriges su tráfico a través del proxy, te desplazas por el panel hasta que se carguen suficientes entradas y analizas el código fuente de la página con BeautifulSoup. Es la opción adecuada cuando necesitas flexibilidad (flujos de clics personalizados, captura de capturas de pantalla, perfiles de empresa con acceso restringido) o tu escala es lo suficientemente pequeña como para gestionar los selectores. Las cinco subsecciones siguientes te guían paso a paso, con código que puedes pegar directamente en un script.

Configurar Selenium Wire para redirigir Chrome a través de un proxy

El truco para extraer reseñas de Google Maps con Selenium consiste en enviar todas las solicitudes a través de un proxy residencial rotativo. Selenium por sí solo no puede pasar las credenciales de autenticación básica HTTP de forma limpia, y ahí es donde entra en juego Selenium Wire. Este expone el bloque de proxy en seleniumwire_options y gestiona el protocolo de autenticación en segundo plano. El patrón de URL de proxy que esperan la mayoría de los proveedores tiene el siguiente aspecto http://<username>:<password>@<host>:<port>, con parámetros adicionales como render o country_code añadidos al nombre de usuario. Comprueba el formato exacto en la documentación actual de tu proveedor antes de ejecutar esto en producción, ya que las convenciones de URL varían.

from seleniumwire import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager

API_KEY = "YOUR_API_KEY"
PROXY = (
    f"http://scrape.render=true.country_code=us:{API_KEY}"
    "@proxy-server.example.com:8001"
)

options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
options.add_argument("--window-size=1920,1080")

sw_options = {"proxy": {"http": PROXY, "https": PROXY, "no_proxy": "localhost,127.0.0.1"}}

driver = webdriver.Chrome(
    service=Service(ChromeDriverManager().install()),
    seleniumwire_options=sw_options,
    options=options,
)
driver.implicitly_wait(30)

El modo sin interfaz gráfica (headless) mantiene un menor uso de memoria en los servidores, y la espera implícita de 30 segundos le da tiempo a Maps para renderizarse antes de que se activen las búsquedas de selectores. Si quieres una introducción más profunda a Selenium, la documentación de enlaces de lenguaje repasa cada opción en detalle.

Carga Google Maps y cierra el cuadro de diálogo de consentimiento de cookies

Una vez que el controlador esté configurado, dirígelo a una URL de búsqueda como https://www.google.com/maps/search/pizza+in+new+york. Maps suele mostrar un cuadro de diálogo de consentimiento de cookies la primera vez que se carga una sesión, y el diseño no te permitirá desplazarte por los resultados hasta que lo cierres. Envuelve el clic en un try/except, ya que el tráfico renderizado por proxy en algunas regiones omite el cuadro de diálogo por completo.

from selenium.webdriver.common.by import By

driver.get("https://www.google.com/maps/search/pizza+in+new+york")

try:
    accept_btn = driver.find_element(
        By.XPATH, "//button[.//span[contains(text(), 'Accept all')]]"
    )
    accept_btn.click()
except Exception:
    print("Cookie consent not shown for this session.")

Registra siempre el error en lugar de dejar que la excepción se propague. Quieres que la ejecución continúe cuando el cuadro de diálogo no esté presente, no que se interrumpa. Si tu configuración regional muestra una etiqueta de botón diferente, cambia el texto XPath o recurre a una aria-label coincidencia en el banner de consentimiento.

Desplaza el panel de resultados para activar los listados de carga diferida

Maps no pagina. A medida que te desplazas por el panel de la izquierda, transmite más listados al DOM y, finalmente, llega a un marcador de fin. Para extraer reseñas de Google Maps a cualquier escala razonable, tienes que controlar ese desplazamiento tú mismo. Hay dos patrones que funcionan bien. El primero utiliza pulsaciones de teclas a través de ActionChains, lo que se asemeja a un usuario real. El segundo utiliza un ejecutor de JavaScript, que es más rápido pero más fácil de rastrear.

import time
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys

def scroll_panel_down(driver, panel_xpath, presses=5, pause_time=1):
    panel = driver.find_element(By.XPATH, panel_xpath)
    actions = ActionChains(driver)
    actions.move_to_element(panel).click().perform()
    for _ in range(presses):
        actions.send_keys(Keys.PAGE_DOWN).perform()
        time.sleep(pause_time)

# Cleaner JS-executor alternative
def scroll_panel_js(driver, panel_xpath, rounds=8, pause=1.2):
    panel = driver.find_element(By.XPATH, panel_xpath)
    for _ in range(rounds):
        driver.execute_script("arguments[0].scrollTop = arguments[0].scrollHeight", panel)
        time.sleep(pause)

Ajusta presses y pause_time en función de tu consulta objetivo. Cinco desplazamientos hacia abajo con una pausa de un segundo es un punto de partida razonable, pero una consulta de una ciudad densa puede necesitar 15 o más rondas antes de que el panel informe 'You've reached the end of the list'. Observa el HTML renderizado y detente cuando dejen de aparecer nuevos resultados.

Analiza los nombres de las empresas, las valoraciones y el número de reseñas con BeautifulSoup

Una vez que el panel haya cargado suficientes entradas, pasa el código fuente de la página a BeautifulSoup y extrae los campos. Los enlaces de clase que aparecen a continuación eran válidos en el momento de escribir este artículo, pero Maps los cambia según su propio calendario, así que realiza siempre una nueva comprobación del DOM antes de una ejecución en producción.

from bs4 import BeautifulSoup

soup = BeautifulSoup(driver.page_source, "lxml")

# These class names rotate. Re-verify before each run.
titles = soup.find_all("a", class_="hfpxzc")        # listing anchors
ratings = soup.find_all("span", class_="MW4etd")      # numeric rating
counts = soup.find_all("span", class_="UY7F9")        # review count

places = []
for i, t in enumerate(titles):
    place = {
        "name": t.get("aria-label") or t.get_text(strip=True),
        "url": t.get("href"),
        "rating": ratings[i].get_text(strip=True) if i < len(ratings) else "N/A",
        "review_count": counts[i].get_text(strip=True) if i < len(counts) else "N/A",
    }
    places.append(place)

Aquí hay dos hábitos de resiliencia que importan. En primer lugar, da preferencia al aria-label atributo al texto visible, ya que la etiqueta es más estable ante los ajustes de la interfaz de usuario. Segundo, utiliza búsquedas seguras para el índice, de modo que una valoración que falte no bloquee el bucle. Si deseas una introducción más profunda a BeautifulSoup, una guía interna sobre patrones de análisis es una lectura complementaria útil para estrategias de selección más avanzadas.

Guarda los resultados en CSV con valores N/A como alternativa

El último paso del Método 1 es escribir los listados analizados en el disco. El CSV está bien para trabajos puntuales, y cambiar a Parquet o a una base de datos es un cambio de una sola línea más adelante.

import csv

with open("maps_pizza_places.csv", "w", encoding="utf-8", newline="") as f:
    writer = csv.writer(f)
    writer.writerow(["name", "rating", "review_count", "url"])
    for p in places:
        writer.writerow([
            p.get("name") or "N/A",
            f"{p['rating']}/5" if p["rating"] != "N/A" else "N/A",
            p.get("review_count") or "N/A",
            p.get("url") or "N/A",
        ])

driver.quit()

Establece siempre como valor predeterminado para los campos que faltan un indicador como N/A en lugar de una celda vacía. Las celdas vacías son ambiguas en los procesos posteriores (¿faltaba el campo o falló el rastreo?), y dificultan las comprobaciones de calidad de los datos. Llamar a driver.quit() al final libera el proceso de Chrome y cualquier conexión de proxy que mantuviera.

Método 2: API SERP (vía de bajo código)

El método 1 está bien para prototipos, pero es pesado. La respuesta de producción más limpia a cómo extraer reseñas de Google Maps a gran escala es delegar el renderizado y la rotación de proxies a una API de scraping y enviar un conjunto de instrucciones JSON que le indique a un navegador headless alojado qué hacer en la página. Se obtiene el mismo HTML final, sin la sobrecarga del navegador local, y el proveedor se encarga de los reintentos y la rotación de proxies que, de otro modo, tendrías que gestionar tú mismo.

La mayoría de los proveedores, incluida nuestra API SERP de WebScrapingAPI, aceptan un conjunto de instrucciones JSON en los encabezados de la solicitud que describen desplazamientos, clics y tiempos de espera. El ejemplo siguiente descarta el banner de cookies, desplaza el panel de resultados varias veces y devuelve el HTML final en una sola solicitud. Confirma los nombres exactos de los encabezados y el esquema de instrucciones consultando la documentación actual del proveedor, ya que estos detalles varían.

import json, requests
from bs4 import BeautifulSoup

API_KEY = "YOUR_API_KEY"
TARGET_URL = "https://www.google.com/maps/search/pizza+in+new+york"

instructions = [
    {"type": "click", "selector": "button[aria-label='Accept all']", "optional": True},
    {"type": "scroll", "selector": "div[role='feed']", "repeat": 8, "delay": 1500},
    {"type": "wait", "value": 2000},
]

headers = {
    "x-api-key": API_KEY,
    "x-render-js": "true",
    "x-instruction-set": json.dumps(instructions),
}

resp = requests.get("https://api.example-scraper.com/v1",
                    params={"url": TARGET_URL}, headers=headers, timeout=120)

soup = BeautifulSoup(resp.text, "lxml")
listings = soup.find_all("div", class_="Nv2PK")  # re-verify class before each run
print(f"Got {len(listings)} listings.")

Hay tres razones por las que merece la pena cambiar a este patrón. En primer lugar, ya no es necesario ejecutar y actualizar Chrome en cada worker. En segundo lugar, el proveedor se encarga de rotar los proxies y reintentar las solicitudes fallidas, lo que elimina la mayor parte del trabajo operativo en los días complicados. En tercer lugar, todo el proceso puede ejecutarse en una tarea cron o una función sin servidor, sin depender del navegador.

Método 3: extraer campos de reseñas individuales (texto, fecha, orden, filtros por tema)

El rastreo a nivel de anuncio te indica qué lugares son importantes, pero el valor empresarial se encuentra un nivel más allá, en el texto real de la reseña. La respuesta más breve a cómo extraer reseñas de Google Maps a nivel de reseña individual es saltarse por completo el análisis sintáctico y utilizar una API estructurada de reseñas de Maps. Buscas el data_id una vez y, a continuación, llamar al punto final de reseñas con los parámetros que necesites.

La estructura es intuitiva. engine selecciona el motor de reseñas de Maps. data_id identifica el lugar. sort_by controla el orden: qualityScore (el valor predeterminado, más relevante), newestFirst, ratingHigho ratingLow. topic_id filtra por un tema específico, por ejemplo, un ID de tema de «Servicios» extraído de la respuesta estructurada (el resumen señalaba un ID de muestra de /m/0f3yyn para su verificación). Campos opcionales como Snippet, Response, y Response.iso_date se indexan desde cero, con la primera reseña en el índice 0.

import requests

params = {
    "engine": "google_maps_reviews",
    "data_id": "0x80dcd1f0c5cb6f53:0xd2c4f5c30e2b7c5a",
    "sort_by": "newestFirst",
    "api_key": "YOUR_API_KEY",
}

r = requests.get("https://api.example-reviews.com/search", params=params, timeout=60).json()

for rev in r.get("reviews", []):
    print({
        "user": rev.get("user", {}).get("name"),
        "rating": rev.get("rating"),
        "date": rev.get("iso_date_of_last_edit"),
        "text": rev.get("snippet", "No review text, rating only"),
        "owner_response": rev.get("response", {}).get("snippet", "No response from owner"),
    })

Los campos que faltan siempre se dejan en blanco por defecto. Los evaluadores suelen dejar una valoración con estrellas sin texto, y la mayoría de los propietarios nunca responden, por lo que el JSON tendrá huecos.

Paginación y obtención de más de la primera tanda de reseñas

Tanto la API como las opciones DIY limitan el primer lote a un número reducido. Según la documentación de los proveedores, una API de reseñas de Maps típica devuelve aproximadamente 10 reseñas por solicitud y expone un next_page_token (o un cursor equivalente) en la respuesta. El bucle de paginación tiene la misma forma que se utilizaría para cualquier API basada en tokens: seguir llamando hasta que falte el campo del token.

all_reviews, token = [], None
while True:
    p = dict(params, **({"next_page_token": token} if token else {}))
    r = requests.get(URL, params=p, timeout=60).json()
    all_reviews.extend(r.get("reviews", []))
    token = r.get("serpapi_pagination", {}).get("next_page_token")
    if not token:
        break

En el lado de Selenium, la paginación consiste simplemente en seguir desplazándose dentro de la pestaña de reseñas de la ficha del lugar. Hay que estar atento al indicador «Has llegado al final de la lista» y detenerse cuando el recuento de reseñas mostradas deje de crecer tras dos desplazamientos consecutivos.

Cómo evitar bloqueos de IP, CAPTCHAs y fallos en los selectores

Una vez que entiendas cómo extraer reseñas de Google Maps de forma mecánica, el juego a largo plazo consiste en evitar el bloqueo. El volumen y el sigilo son una compensación, no un ajuste fijo. La palanca más importante es tu conjunto de proxies. Las IP de centros de datos se marcan en las consultas de Maps mucho más rápido que las residenciales, así que una vez que superes unas pocas docenas de solicitudes por hora, planifica rotar por IP residenciales con segmentación a nivel de país. Incorpora esperas aleatorias entre acciones (entre 300 y 1500 ms es un rango razonable), retrocede exponencialmente ante los 429 y limita siempre los reintentos para que un objetivo defectuoso no se coma todo tu presupuesto.

La deriva del selector es el segundo modo de fallo. Trata los hooks como hfpxzc, MW4etd, y Nv2PK como volátiles. Crea un paso de monitorización del DOM ligero que falle de forma evidente cuando un selector deje de coincidir con nada, da preferencia a aria-label y los selectores estructurales a los nombres de clase siempre que puedas, y mantén al menos un plan de respaldo por cada campo crítico. Vale la pena marcar como favorito una breve hoja de consejos sobre señales de bloqueo comunes y cómo esquivarlas, y la guía más extensa de nuestro equipo sobre cómo evitar bloqueos de IP profundiza en la rotación de encabezados y la identificación de huellas digitales (una lectura complementaria útil cuando un script que antes era estable de repente empieza a devolver errores 403).

Limpieza, almacenamiento y análisis de los datos de reseñas extraídos

El objetivo de todo esto es obtener datos listos para la toma de decisiones, no un CSV gigante. Un breve proceso de posprocesamiento convierte las reseñas sin procesar en algo sobre lo que un equipo de producto o de marketing pueda actuar.

import pandas as pd
from textblob import TextBlob

df = pd.DataFrame(all_reviews)
df = df.drop_duplicates(subset=["review_id"])  # dedupe
df["rating"] = df["rating"].astype(float).clip(0, 5)  # normalize
df["text"] = df["snippet"].fillna("").str.replace(r"[\u200b-\u200f]", "", regex=True)
df["sentiment"] = df["text"].apply(lambda t: TextBlob(t).sentiment.polarity if t else 0.0)

Cuatro pasos hacen la mayor parte del trabajo: deduplicar review_id, recortar las puntuaciones a un rango de 0 a 5, eliminar el ruido de caracteres de ancho cero y emojis del texto, y etiquetar la polaridad del sentimiento por fila con una biblioteca ligera de PLN. A partir de ahí, es un paso directo de Pandas a SQL o de Pandas al almacén de datos. Ese resultado es lo que alimenta un panel de control de reseñas o una comparativa del sentimiento de la competencia, lo que cierra el círculo y nos lleva de vuelta a los casos de uso con los que empezamos.

Conclusiones clave

  • La API oficial de Google Places es útil para integrar algunas reseñas en un producto, pero sus límites por lugar la convierten en una herramienta inadecuada para el análisis o la investigación de la competencia.
  • Una combinación de Selenium y proxies residenciales te ofrece el máximo control. Ten en cuenta los banners de cookies, la carga basada en el desplazamiento y los ganchos de clases CSS rotativas como hfpxzc y Nv2PK.
  • Una API de scraping con un conjunto de instrucciones de renderizado JSON elimina por completo el navegador local y es la vía más limpia para tareas programadas y repetibles.
  • Una API de reseñas de Maps estructurada es la vía más rápida para limpiar los campos de cada reseña. Utiliza sort_by, topic_idy next_page_token para controlar la profundidad y el corte.
  • Trata el proceso como un proceso. Elimina duplicados mediante review_id, normaliza las valoraciones, elimina el ruido y etiqueta el sentimiento para que el resultado esté listo para la toma de decisiones, no solo almacenado.

Preguntas frecuentes

En muchas jurisdicciones se acepta generalmente que los datos de reseñas públicas se pueden extraer cuando se utilizan para análisis o investigación, pero las Condiciones de servicio de Google restringen el acceso automatizado a sus productos, y la jurisprudencia estadounidense sobre la extracción de datos públicos sigue evolucionando. Comprueba siempre las condiciones de Maps, respeta robots.txt, evita extraer datos personales más allá de lo que es visible públicamente y consulta a un abogado antes de cualquier uso comercial.

¿Por qué no utilizar simplemente la API oficial de Google Places en lugar de un rastreador?

La API de Places tiene un límite de solicitudes, requiere un proyecto de Google Cloud de pago y solo devuelve un pequeño subconjunto de las reseñas que se muestran en la interfaz de usuario de Maps. Eso la hace adecuada para integrar unas pocas reseñas en un producto, pero inviable para el análisis de opiniones, la evaluación comparativa de la competencia o cualquier caso de uso que requiera una muestra representativa.

¿Puedo extraer reseñas de Google Maps sin Selenium o un navegador sin interfaz gráfica?

No de forma fiable con datos sin procesar requests, ya que Maps es una SPA con mucho JavaScript. Las alternativas realistas son una API de scraping que ejecute un navegador sin interfaz de usuario alojado por ti, o una API de reseñas estructurada que devuelva JSON analizado sin renderizar nada en el lado del cliente.

¿Con qué frecuencia cambian las clases CSS de Google Maps y cómo mantengo mi rastreador al día?

Con la suficiente frecuencia como para que no des por sentado que ningún gancho de clase es permanente. Protégete contra las desviaciones con aria-label selectores, alternativas estructurales de XPath, una pequeña tarea de monitorización del DOM que avise claramente cuando un selector no encuentre coincidencias, y una alerta que te avise antes de la siguiente ejecución programada.

¿Cuántas reseñas puedo extraer por negocio en una sola ejecución y cómo funciona la paginación?

Una API de reseñas de Maps típica devuelve unas 10 reseñas por solicitud y un next_page_token cursor para el siguiente lote. No hay un límite total fijo, pero las reseñas muy antiguas son más difíciles de recuperar. Recorre los tokens hasta que no se devuelva ninguno y, en el lado de Selenium, sigue desplazándote por la pestaña de reseñas hasta que el recuento deje de crecer.

Conclusión

No hay una única respuesta correcta sobre cómo extraer reseñas de Google Maps. La respuesta correcta depende de la cantidad de datos que necesites, la frecuencia con la que los necesites y el esfuerzo operativo que puedas asumir. Para una auditoría puntual de las ubicaciones de un competidor, Selenium más un proxy residencial es más que suficiente. Para un proceso de análisis de opiniones recurrente que debe seguir funcionando mientras Google cambia los nombres de las clases y refuerza su sistema antibots, una API de scraping gestionada o una API estructurada de reseñas de Maps es la solución que te permitirá dormir tranquilo.

Sea cual sea el método que elijas, trata el resultado como datos y no como HTML. Elimina duplicados por ID de reseña, normaliza las puntuaciones, elimina el ruido, puntúa el sentimiento y cárgalo en algún lugar consultable para que el trabajo dé sus frutos en un panel de control o un modelo, en lugar de en un CSV obsoleto.

Si prefieres no tener que gestionar y mantener una flota de Chrome solo para estar al día de los cambios en la interfaz de Maps, nuestra API Scraper SERP de WebScrapingAPI se encarga de la rotación de proxies, el renderizado sin interfaz y la resolución de CAPTCHAs desde un único punto de acceso, por lo que puedes conservar el código Python de esta guía y simplemente cambiar la capa de obtención de datos. Genera una clave API, dirígela a una URL de Maps y empieza a recopilar datos de reseñas limpios en una tarde.

Acerca del autor
Andrei Ogiolan, Desarrollador Full Stack @ WebScrapingAPI
Andrei OgiolanDesarrollador Full Stack

Andrei Ogiolan es desarrollador full stack en WebScrapingAPI, donde colabora en todas las áreas del producto y ayuda a crear herramientas y funciones fiables para la plataforma.

Empieza a crear

¿Estás listo para ampliar tu recopilación de datos?

Únete a más de 2000 empresas que utilizan WebScrapingAPI para extraer datos de la web a escala empresarial sin ningún gasto de infraestructura.