Búqueda en tiempo real automatizada con Google Maps y Selenium
Tags: python, googlesearch, realtime, selenium
Published: 2023-12-29 09:58:15

## Introducción

En el mundo en el que vivimos la automatización de procesos se ha convertido en un pilar fundamental para mejorar la eficiencia y reducir costes. En este artículo, voy a explorar contigo cómo automatizar la búsqueda de información en Google Maps y la captura de imágenes de ubicaciones utilizando Python mediante un script que combina las bibliotecas `googlemaps` y `selenium`.

## Background

Python se ha posicionado como un lenguaje líder para la automatización de tareas gracias a su simplicidad y a la amplia gama de bibliotecas disponibles. En nuestro caso, utilizaremos:

- **googlemaps**: Para interactuar con la API de Google Maps.
- **selenium**: Para automatizar acciones en navegadores web.

```
import googlemaps

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from webdriver_manager.chrome import ChromeDriverManager

# otras librerías auxiliares

import re
import time
import logging
```

Google Maps ofrece una API con muchas funcionalidades que permite a los desarrolladores acceder a datos y funcionalidades de mapas. Utilizaremos esta API para buscar comercios por nombre y obtener sus coordenadas.

## Hands On

El código completo para realizar la búsqueda en Google Maps es el siguiente:

```
def buscar_en_google_maps(nombre_comercio, google_maps_key, location, radius=5000):
    gmaps = googlemaps.Client(key=google_maps_key)
    
    print(f"Voy a buscar este comercio {nombre_comercio}")
    resultados = gmaps.places(query=nombre_comercio, location=location, radius=radius)

    # Extraer la URL del primer resultado
    if resultados['results']:
        place_id = resultados['results'][0]['place_id']
        # Construir la URL de Google Maps
        url = f"https://www.google.com/maps/place/?q=place_id:{place_id}"
        return url
    return None

# Tu clave API de Google Maps
GOOGLE_MAPS_KEY = 'tu-clave-api-key'

# Coordenadas de tu ubicación (latitud, longitud)
LOCATION = (X,Y)  # reemplaza con las coordenadas correctas

# lista de nombres de comercios
nombres_comercios = ['Comercio Local 1, 'Comercio Local 2, 'Comercio Local 3']

# Buscar cada comercio en Google Maps
for nombre in nombres_comercios:
    resultados = buscar_en_google_maps(nombre, GOOGLE_MAPS_KEY, LOCATION)
    # Procesar y almacenar los resultados según sea necesario
    print(resultados)
```

El script se divide en varias secciones funcionales:

**Búsqueda en Google Maps:**

**1.Utiliza la API de Google Maps para buscar un comercio por nombre**. Esta es la definición de la función `buscar_en_google_maps`:

**Parámetros:**

- **nombre_comercio**: El nombre del comercio que se quiere buscar.
- **google_maps_key**: La clave API para acceder a los servicios de Google Maps.
- **location**: Las coordenadas geográficas (latitud y longitud) cerca de donde se realizará la búsqueda.
- **radius**: El radio en metros dentro del cual se desea buscar, con un valor predeterminado
 de 5000 metros.

**2.Extrae la URL de la ubicación del primer resultado.**

- Se utiliza el método `places` del cliente de Google Maps para buscar comercios.
- Se pasan el nombre del comercio, la ubicación y el radio como argumentos para el método places.
- Si hay resultados, se extrae el `place_id` del primer comercio encontrado.
- Se construye y devuelve una URL de Google Maps que apunta directamente al comercio utilizando su `place_id`.

**Automatización con Selenium:**

El código completo para automatizar la captura de información en el navegador utilizando `Selenium` es el siguiente:

```
def click_zoom_in(driver, times):
    try:
        zoom_in_button = WebDriverWait(driver, 10).until(
            EC.element_to_be_clickable((By.ID, "widget-zoom-in"))
        )
        for _ in range(times):
            zoom_in_button.click()
            time.sleep(1)  # Espera breve entre cada clic
        time.sleep(5)  # Espera adicional para que el mapa se actualice después del último clic
    except Exception as e:
        logger.warning(f"No se pudo realizar el zoom: {e}")

def accept_cookies(driver):
    try:
        logger.info("Buscando el botón de aceptar cookies")
        accept_cookies_button = WebDriverWait(driver, 10).until(
            EC.element_to_be_clickable((By.XPATH, "//span[contains(text(), 'Aceptar todo')]"))
        )
        accept_cookies_button.click()
        logger.info("Cookies aceptadas")
    except Exception as e:
        logger.warning(f"No se encontró el botón de aceptar cookies: {e}")


def format_filename(name):
    # Eliminar caracteres especiales y reemplazar espacios por guiones bajos
    return re.sub(r'[^\w\s-]', '', name).replace(' ', '_')


def capture_webpage_screenshot(url, path_to_save_image):
    try:
        logger.info("Iniciando el servicio de ChromeDriver")
        service = Service(ChromeDriverManager().install())

        logger.info("Creando una instancia del driver de Chrome")
        driver = webdriver.Chrome(service=service)
        
        logger.info(f"Accediendo a la URL: {url}")
        driver.get(url)

        # Intenta aceptar las cookies
        accept_cookies(driver)

        # Realizar zoom en la página
        click_zoom_in(driver, 1)  # Ajusta este número según sea necesario

        driver.set_window_size(1920, 1080)  # Ajusta según necesites

        logger.info(f"Guardando captura de pantalla en: {path_to_save_image}")
        driver.save_screenshot(path_to_save_image)
    except Exception as e:
        logger.error(f"Se produjo un error: {e}")
    finally:
        logger.info("Cerrando el driver de Chrome")
        driver.quit()

def process_comercios(comercios, google_maps_key, location):
    for comercio in comercios:
        url = buscar_en_google_maps(comercio['info'], google_maps_key, location)
        if url:
            filename = format_filename(comercio['info']) + ".png"
            path_to_save_image = "ruta-para-guardar-la-imagen"
            capture_webpage_screenshot(url, path_to_save_image)

```

```
# Ejemplo de uso

# lista de nombres de comercios
nombres_comercios = ['Comercio Local 1, 'Comercio Local 2, 'Comercio Local 3']

# Tu clave API de Google Maps
GOOGLE_MAPS_KEY = 'tu-clave-api-key'

# Coordenadas de tu ubicación (latitud, longitud)
LOCATION = (X,Y)  # reemplaza con las coordenadas correctas

process_comercios(nombres_comercios, GOOGLE_MAPS_KEY, LOCATION)
```

Selenium inici un navegador automatizado:

**- Realiza acciones como aceptar cookies y hacer zoom.**
**- Accede a la URL de Google Maps y captura una imagen de la ubicación.**
**- Guarda la imagen en un directorio específico.**

**Función click_zoom_in:**

- Objetivo: Hacer zoom en la página web un número específico de veces.
- Parámetros: driver (el navegador automatizado de Selenium), times (número de veces para hacer zoom).
- Método: Utiliza WebDriverWait y expected_conditions para esperar hasta que el botón de zoom esté disponible y luego hace clic en él el número de veces especificado.

**Función accept_cookies:**

- Objetivo: Aceptar las cookies en una página web.
- Parámetro: driver (navegador automatizado).
- Método: Busca y hace clic en el botón para aceptar todas las cookies.

**Función format_filename:**

- Objetivo: Formatear los nombres para ser usados como nombres de archivos.
- Método: Elimina caracteres especiales y reemplaza espacios por guiones bajos.

**Función capture_webpage_screenshot:**

- Objetivo: Capturar y guardar una captura de pantalla de una URL.
- Parámetros: url (URL de la página a capturar), path_to_save_image (ruta donde guardar la imagen).
- Método: Inicia un navegador Chrome automatizado, accede a la URL, acepta cookies, hace zoom y captura una captura de pantalla de la página.

**Función process_comercios:**

- Objetivo: Procesar una lista de comercios, obtener sus URLs de Google Maps y capturar capturas de pantalla de sus ubicaciones.
- Método: Itera sobre una lista de comercios, llama a la función buscar_en_google_maps para obtener la URL, y luego llama a capture_webpage_screenshot para capturar y guardar una captura de pantalla.

El script se prueba con una lista de nombres de comercios en una ubicación específica. Cada comercio se busca en Google Maps, y se captura una imagen de su ubicación.

## Conclusión

Este script es un ejemplo práctico de cómo Python se puede utilizar para automatizar tareas complejas como la búsqueda de información en mapas y la captura de imágenes. La combinación de estas bibliotecas ofrece una solución flexible para cubrir diferentes necesidades de automatización dependiendo de tu sector o proyecto.

**What's Next, próximos pasos:**

- [Búqueda en tiempo real automatizada con Google Maps y Selenium](https://dev.to/albertgilopez/buqueda-en-tiempo-real-automatizada-con-google-maps-y-selenium-21h7)
- [Web scraping para extraer información utilizando requests y BeautifulSoup en Python](https://dev.to/albertgilopez/web-scraping-para-extraer-informacion-utilizando-requests-y-beautifulsoup-en-python-mmm)
- [Gemini AI: Extracción de datos estructurados con Gemini Pro Vision y Pydantic
](https://medium.com/@jddam/extracci%C3%B3n-de-datos-estructurados-con-gemini-pro-vision-y-pydantic-345577edb344)
- [Gemini AI: Data mining, extracción de información, topics, keywords y etiquetas](https://medium.com/@jddam/gemini-ai-data-mining-extracci%C3%B3n-de-informaci%C3%B3n-topics-keywords-y-etiquetas-dae2caa698ea)

**Comparte tu experiencia:**
Estoy abierto a colaborar y discutir sobre las posibilidades que ofrece la inteligencia artificial y cómo trabajar juntos para explorar y construir soluciones innovadoras. Si tienes ideas, preguntas o simplemente quieres hablar de ello, escríbeme:

GitHub: [https://github.com/albertgilopez](https://github.com/albertgilopez)
LinkedIn: [https://www.linkedin.com/in/albertgilopez/](https://www.linkedin.com/in/albertgilopez/)
Inteligencia Artificial Generativa en español: [https://www.codigollm.es/](https://www.codigollm.es/)