Construyendo un buscador de productos dentro de Odoo: ltc_price_hunter

De un corte de luz a un buscador de productos

La semana pasada un corte de luz tiro abajo todo mi laboratorio casero: tres servidores Proxmox, un NAS QNAP, equipos de red y mi puesto de trabajo. Despues del tercer apagon en un mes, decidi que era hora de comprar un SAI. Pero en vez de navegar por Amazon, construi la herramienta que navega por mi.

El problema

Necesitaba un SAI dimensionado para mi carga real. Eso significaba saber exactamente cuanto consume mi laboratorio. Me conecte por SSH a cada maquina y audite el hardware real:

  • pve1 - Xeon E5-2697 v3, 64 GB RAM, 4 TB NVMe + 4 TB HDD - ~121 W
  • host1 - Xeon E5-2680 v4, 32 GB RAM, 500 GB NVMe + 4 TB HDD - ~102 W
  • pbs - AMD FX-8350, 18 GB RAM, 3x HDD (el que mas consume) - ~136 W
  • QNAP TS-433 - ARM Cortex-A55, 4x 4 TB RAID 5 - ~38 W

Total: 397 W tipicos, 9 HDDs y 2 unidades NVMe. Con perifericos (monitores, router, switch) el laboratorio completo consume ~485 W. Un SAI de 1500 VA da 5-10 minutos para un apagado ordenado de las VMs.

La solucion: ltc_price_hunter

En vez de comparar precios manualmente entre tiendas, cree un modulo de Odoo 16 llamado ltc_price_hunter. Es un buscador de productos que rastrea tiendas reales, extrae especificaciones tecnicas, puntua los resultados segun tus requisitos y escribe todo de vuelta en Odoo para su revision.

Formulario de busqueda de Price Hunter en Odoo

El formulario de busqueda: define lo que necesitas, establece precios objetivo, anade palabras clave y etiquetas preferidas.

Arquitectura

El modulo tiene 6 modelos:

  • price.hunter.source - registro de marketplaces (Amazon ES, PcComponentes, AliExpress)
  • price.hunter.search - lo que estas buscando (marca, modelo, rango de precios, palabras clave)
  • price.hunter.session - una ejecucion de scraping por fuente (duracion, estado, seguimiento de errores)
  • price.hunter.listing - un producto encontrado (precio, valoracion, vendedor, disponibilidad, envio)
  • price.hunter.spec - especificaciones tecnicas como pares clave-valor (el diferenciador clave)
  • price.hunter.tag - etiquetas de clasificacion (prime, envio gratis, en stock, etc.)

El problema de la extraccion de especificaciones

Esto es lo que hace a Price Hunter diferente de un simple comparador de precios. Cada marketplace estructura las especificaciones de producto de forma distinta:

  • Amazon usa tablas HTML con IDs como #productDetails_techSpec_section_1
  • PcComponentes usa listas UL/LI con pares clave:valor separados por dos puntos
  • AliExpress usa clases CSS ofuscadas que cambian frecuentemente

Un spec_extractor.py compartido normaliza los nombres de especificaciones entre fuentes, de modo que "Potencia de salida", "Output Power" y "Potencia" se mapean a la misma clave. Esto permite comparacion entre fuentes en una sola vista de Odoo.

Detalle de listing con 50 especificaciones tecnicas

Un listing de PcComponentes con 50 especificaciones extraidas: topologia, capacidad, potencia, bateria, dimensiones y mas.

Formula de puntuacion

Cada listing recibe una puntuacion de coincidencia (0.0 a 1.0) basada en criterios ponderados:

  • 35% similitud de texto (marca, modelo, coincidencia de palabras clave)
  • 25% ajuste de precio (distancia al precio objetivo)
  • 15% coincidencia de especificaciones (cuantas specs requeridas estan presentes)
  • 10% alineacion de etiquetas (preferidas vs evitadas)
  • 10% calidad de valoraciones (estrellas ponderadas por numero de resenas)
  • 5% velocidad de envio (penaliza envio lento: >15 dias = 0.1 de puntuacion)

Los listings con puntuacion ≥ 0.85 se marcan como "hot leads".

El plugin ECC

El scraping lo gestiona un plugin de Claude Code (ltc-price-hunter) con tres agentes especializados que se ejecutan en paralelo:

Sesiones de scraping en tres marketplaces

Sesiones de las tres fuentes: Amazon ES, PcComponentes y AliExpress. Cada sesion registra duracion, estado y listings encontrados.

  • Coordinador - parsea consultas en lenguaje natural, crea registros en Odoo, despacha scrapers en paralelo
  • Agente Amazon - basado en Playwright, gestiona consentimiento de cookies, extrae de paginas de detalle de producto
  • Agente PcComponentes - usa busqueda Google site: para evitar Cloudflare Turnstile
  • Agente AliExpress - traduce terminos de busqueda del espanol al ingles, ampliacion progresiva de consultas, maneja selectores ofuscados

Primera busqueda real: encontrando mi SAI

La primera busqueda en produccion fue "SAI CyberPower 1500VA senoidal NUT compatible", precio objetivo 200 EUR, maximo 400 EUR:

Resultados de busqueda de Amazon ES

Resultados de Amazon ES: 20 modelos CyberPower UPS con precios, valoraciones, disponibilidad y puntuaciones de coincidencia.

  • Amazon ES: 20 listings en 108 segundos, sin bloqueos. Modelos CyberPower de 69 a 393 EUR
  • PcComponentes: 1 listing (el CyberPower CP1500EPFCLCD exacto a 390,99 EUR con 50 especificaciones tecnicas)
  • AliExpress: 7 listings en 184 segundos. Mayormente modelos alternativos; envio de 30 dias desde China penalizado en la puntuacion

Total: 28 listings de productos reales con mas de 244 especificaciones tecnicas extraidas, todo consultable en Odoo.

Lo que aprendi

  • Cada marketplace lucha contra los scrapers de forma diferente. Amazon tolera navegadores headless con perfiles persistentes. PcComponentes bloquea la busqueda directa via Cloudflare Turnstile (la busqueda Google site: funciona). AliExpress ofusca las clases CSS en cada despliegue.
  • La normalizacion de especificaciones es mas dificil que el scraping. La misma especificacion aparece con diferentes nombres, unidades e idiomas entre fuentes. Un normalizador compartido es esencial.
  • La velocidad de envio importa para la puntuacion. Sin la penalizacion del 5% por envio, un listing de 15 EUR en AliExpress con 45 dias de envio superaria a uno de 200 EUR en Amazon con entrega al dia siguiente.
  • El modulo replica ltc_second_hand. Misma arquitectura (source/search/session/listing), mismo modelo de seguridad, mismo patron de plugin ECC. La unica adicion es el modelo de especificaciones para datos tecnicos estructurados.

Veredicto del SAI

Despues de todo esto? El CyberPower CP1500EPFCLCD: 1500 VA / 900 W, onda senoidal pura, compatible con NUT via USB HID, alrededor de 200 EUR en Amazon ES. Conectado a pve1 como NUT master, con host1 y pbs como NUT slaves. El laboratorio sobrevive a los cortes de luz, y tengo un buscador de productos para la proxima compra.

eBay y Odoo: montando un rastreador de segunda mano en una sesion
De keyset Non Compliant a 65 anuncios reales: credenciales Browse API, un bug de ref() y el primer dispatch real de cuatro scrapers de marketplaces.