Web Scraping de productos de Tottus.com
EL presente proyecto se hace con fines demostrativos, la data extraída no se usa para fines comerciales.
# Importando librerías
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.common.by import By
import pandas as pd
import logging
# Función que obtiene el precio de un item/producto
def obtener_precio(item, selector):
    elementos = item.find_elements(By.CSS_SELECTOR, selector)
    return float(elementos[0].get_attribute(selector[3:-1]).replace(",", "").strip()) if elementos else 0
Producto a buscar
Parámetro de precio
# Configurando el logging
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
# Opciones de configuración del navegador
firefox_options = Options()
firefox_options.add_argument("--headless")
firefox_options.add_argument("--no-sandbox")
firefox_options.add_argument("--disable-dev-shm-usage")
# Creando una instancia del navegador
driver = webdriver.Firefox(options=firefox_options)
# Seteando el término de búsqueda, precio límite y la URL de la página a scrapear
termino_busqueda = termino_busqueda if termino_busqueda else "refrigeradora"
precio_limite = float(precio_limite) if precio_limite else 1800
url = f"https://tottus.falabella.com.pe/tottus-pe/search?Ntt={termino_busqueda}"
try:
    # Obteniendo el URL
    driver.get(url)
    logging.info(f"URL procesada correctamente: {url}")
    # Buscando productos resultados para el término ingresado
    listado_marcas = driver.find_elements(By.CLASS_NAME, "title-rebrand")
    listado_productos = driver.find_elements(By.CLASS_NAME, "subTitle-rebrand")
    listado_precios = driver.find_elements(By.CLASS_NAME, "prices")
    # Verificando que todos los listados tienen el mismo tamaño
    if not (len(listado_marcas) == len(listado_productos) == len(listado_precios)):
        logging.warning("La cantidad de marcas, productos y precios no coincide.")
        raise ValueError("Inconsistencia en el tamaño de las listas. No se puede continuar.")
    # Creando tabla de resultados
    resultados = []
    for marca, producto, precio in zip(listado_marcas, listado_productos, listado_precios):
        try:
            # Obteniendo la marca y nombre del producto
            marca_texto = marca.text.strip()
            producto_texto = producto.text.strip()
            
            # Extrayendo precios usando la función
            precio_cmr = obtener_precio(precio, "li[data-cmr-price]")
            precio_internet = obtener_precio(precio, "li[data-internet-price]")
            precio_normal = obtener_precio(precio, "li[data-normal-price]")
            # Validando status precio límite
            if precio_cmr != 0:
                buen_precio = "SI" if precio_cmr <= precio_limite else "NO"
            else:
                buen_precio = "SI" if precio_internet <= precio_limite else "NO"
            # Agregando los resultados a una lista
            resultados.append([
                marca_texto,
                producto_texto,
                "S/{:,.2f}".format(precio_cmr),
                "S/{:,.2f}".format(precio_internet),
                "S/{:,.2f}".format(precio_normal),
                buen_precio
            ])
        except Exception as e:
            logging.error(f"Error al procesar producto: {e}")
    # Creando un DataFrame con los resultados
    tabla_resultado = pd.DataFrame(resultados, columns=["MARCA", "PRODUCTO", "PRECIO CMR", "PRECIO INTERNET", "PRECIO TIENDA", "BUEN PRECIO"])
    logging.info("Proceso completado correctamente.")
    logging.info(f"CATEGORÍA: {termino_busqueda.upper()} | CANT. DE RESULTADOS: {len(tabla_resultado)}")
except Exception as e:
    logging.error(f"Ocurrió un error durante la ejecución: {e}")
finally:
    driver.quit()
    logging.info("Navegador cerrado. Ejecución finalizada.")
# Mostrando resultados
tabla_resultado