Skip to main content

Biblioteca Python para parsing de preços de scraping, cálculo de descontos e análise estatística de histórico de preços.

Project description

notify-utils

Python Version Version License

Biblioteca Python completa para análise de preços de e-commerce: parsing, validação, cálculo de descontos reais e detecção de promoções falsas através de análise estatística de histórico.

🎯 Funcionalidades

  • Parser de Preços: Normaliza strings de preços de diferentes formatos (BR, US)
  • Parsers de Lojas: Extração automática de produtos de APIs/HTML específicas (Nike, Maze Shop, Beleza na Web)
  • Cálculo de Descontos Inteligente: Detecta descontos reais vs anunciados usando histórico
  • Análise Estatística Avançada: Média, mediana, tendências, volatilidade e confiança
  • Sistema de Validação de Preços: Estratégias inteligentes para validar preços antes de adicionar ao histórico
  • Ajuste Automático de Período: Garante inclusão de histórico mais recente
  • Filtro de Ruído: Ignora dados voláteis recentes (scraping com erros)
  • Notificações Discord: Envio de alertas de preço via webhook (opcional)

Instalação

pip install notify-utils

Uso Básico

Parsing de Preços

from notify_utils import parse_price

preco = parse_price("R$ 1.299,90")  # → 1299.90
preco = parse_price("$1,299.90")    # → 1299.90

Cálculo de Desconto com Histórico

from notify_utils import Price, get_discount_info
from datetime import datetime, timedelta

# Histórico de preços
precos = [
    Price(value=1299.90, date=datetime.now() - timedelta(days=60)),
    Price(value=1199.90, date=datetime.now() - timedelta(days=30)),
]

# Calcular desconto real baseado no histórico
info = get_discount_info(
    current_price=899.90,
    price_history=precos,
    period_days=30
)

print(f"Desconto real: {info.discount_percentage:.2f}%")
print(f"É desconto real? {info.is_real_discount}")

Análise de Tendência

from notify_utils import calculate_price_trend

trend = calculate_price_trend(precos, days=30)

print(f"Direção: {trend.direction}")  # 'increasing', 'decreasing', 'stable'
print(f"Mudança: {trend.change_percentage:.2f}%")
print(f"Confiança: {trend.confidence}")

Validação de Preços com Estratégias

from notify_utils import PriceHistory, Price, PriceAdditionStrategy, PriceAction

history = PriceHistory(product_id="PROD123", prices=precos)

# Estratégia SMART: aceita quedas imediatas, aumentos após 24h
novo_preco = Price(value=899.90, date=datetime.now())
result = history.add_price(
    novo_preco,
    strategy=PriceAdditionStrategy.SMART,
    min_hours_for_increase=24
)

# Integração com banco de dados
if result.action == PriceAction.ADDED:
    db.insert_price(product_id, result.affected_price)
    print(f"✅ Preço adicionado: R$ {result.affected_price.value:.2f}")
elif result.action == PriceAction.REJECTED:
    print(f"⏭️  Ignorado: {result.reason}")

Ajuste Automático de Período e Filtro de Ruído

from notify_utils import get_discount_info

# Ajusta período automaticamente + ignora 3 dias mais recentes
info = get_discount_info(
    current_price=899.90,
    price_history=precos,
    period_days=30,
    auto_adjust_period=True,  # Inclui histórico mais recente
    skip_recent_days=3        # Ignora ruído de 0-2 dias
)

print(f"Período solicitado: {info.period_days} dias")
print(f"Período ajustado: {info.adjusted_period_days} dias")
print(f"Dias ignorados: {info.skip_recent_days}")
print(f"Amostras usadas: {info.samples_count}")

Parser HTML - Beleza na Web

from notify_utils import ParserFactory, StoresParserEnum

# Obter parser para Beleza na Web (HTML)
parser = ParserFactory.get_parser(StoresParserEnum.BELEZA_NA_WEB_HTML)

# Parse HTML (deduplica automaticamente produtos repetidos em carrosséis)
with open('beleza.html', 'r', encoding='utf-8') as f:
    html = f.read()

products = parser.from_html(html)

# Processar produtos extraídos
for product in products:
    print(f"{product.name}")
    print(f"  Preço atual: R$ {product.current_price_float:.2f}")
    if product.old_price_float > 0:
        desconto_pct = ((product.old_price_float - product.current_price_float) / product.old_price_float) * 100
        print(f"  Desconto: {desconto_pct:.1f}%")

Características:

  • ✅ Parse híbrido (JSON embedded no data-event + HTML estruturado)
  • ✅ Deduplicação automática por SKU (carrosséis repetem produtos)
  • ✅ Extrai ~36 produtos únicos de ~430 repetições no HTML
  • ✅ Preços, URLs, imagens e metadados completos

Notificações Discord

from notify_utils import Product, DiscordEmbedBuilder

produto = Product(
    product_id="PROD123",
    name="Notebook Gamer",
    url="https://loja.com/produto"
)

builder = DiscordEmbedBuilder()
embed = builder.build_embed(produto, info, precos)
# Enviar via webhook Discord

📊 Estratégias de Validação

A biblioteca oferece 4 estratégias para adicionar preços ao histórico:

Estratégia Comportamento Uso Recomendado
ALWAYS Sempre adiciona Testes, coleta sem filtro
ONLY_DECREASE Apenas quedas Alertas de promoção
SMART Quedas imediatas + aumentos após tempo mínimo Produção (padrão)
UPDATE_ON_EQUAL Atualiza timestamp se preço igual Rastreamento de estabilidade

🔧 Casos de Uso

1. Sistema de Scraping com Parsers e Validação

from notify_utils import (
    ParserFactory, StoresParserEnum,
    PriceHistory, Price, PriceAdditionStrategy, PriceAction
)

# 1. Extrair produtos da API da loja
parser = ParserFactory.get_parser(StoresParserEnum.MAZE_API_JSON)
products = parser.from_json(api_response)

# 2. Processar cada produto
for product in products:
    # Carregar histórico do banco
    prices_from_db = db.get_prices(product.product_id)
    history = PriceHistory(product_id=product.product_id, prices=prices_from_db)

    # Validar e adicionar novo preço
    novo_preco = Price(value=product.current_price, date=datetime.now())
    result = history.add_price(novo_preco, strategy=PriceAdditionStrategy.SMART)

    if result.action == PriceAction.ADDED:
        db.insert_price(product.product_id, result.affected_price)

        # Notificar se queda >= 10%
        if result.status.value == "decreased" and abs(result.percentage_difference) >= 10:
            notifier.send_price_alert(product, discount_info, history.prices)

2. Pipeline Completo: API → Validação → Notificação

# Fluxo completo automatizado
def pipeline_completo(store: StoresParserEnum, api_data: dict):
    # Passo 1: Parsing
    parser = ParserFactory.get_parser(store)
    products = parser.from_json(api_data)

    for product in products:
        # Passo 2: Validação com histórico
        history = PriceHistory(product_id=product.product_id,
                              prices=db.get_prices(product.product_id))

        novo_preco = Price(value=product.current_price, date=datetime.now())
        result = history.add_price(novo_preco, strategy=PriceAdditionStrategy.SMART)

        # Passo 3: Persistência
        if result.action == PriceAction.ADDED:
            db.insert_price(product.product_id, result.affected_price)

        # Passo 4: Análise de desconto
        info = get_discount_info(
            current_price=product.current_price,
            price_history=history.prices,
            period_days=30
        )

        # Passo 5: Notificação se desconto real
        if info.is_real_discount and info.discount_percentage >= 15:
            discord_notifier.send_price_alert(product, info, history.prices)

3. Detecção de Promoções Falsas

# Loja anuncia "De R$ 1.999 por R$ 899" (50% off!)
# Mas histórico mostra que preço real era R$ 1.299

info = get_discount_info(
    current_price=899.90,
    price_history=precos_historicos,
    advertised_old_price=1999.90  # IGNORADO quando há histórico!
)

print(f"Desconto anunciado: 55%")
print(f"Desconto REAL: {info.discount_percentage:.2f}%")  # ~31% (vs R$ 1.299)
print(f"Estratégia: {info.strategy}")  # 'history' (priorizou histórico)

4. Análise de Melhor Momento para Comprar

trend = calculate_price_trend(precos, days=30)

if trend.is_decreasing() and trend.has_high_confidence():
    print("✅ Tendência de queda com alta confiança - BOM momento!")
elif trend.is_increasing() and trend.is_accelerating:
    print("⚠️ Preço subindo rápido - compre agora ou espere próxima promoção")

📚 Documentação Completa

Para mais detalhes e exemplos avançados, consulte:

  • CLAUDE.md - Documentação completa com arquitetura e exemplos
  • notify_utils/ - Código fonte com docstrings detalhadas

🛠️ Requisitos

  • Python >= 3.12
  • discord-webhook >= 1.4.1 (opcional, apenas para notificações)

📝 Changelog

v0.2.3 (2026-02-05)

  • 🏪 SephoraAPIJSONParser Completo: Parser para API Linx Impulse da Sephora Brasil
  • 🔄 Expansão de SKUs: 1 produto com N variações → N produtos únicos (36 → 105 SKUs)
  • 📦 Nome Combinado: Formato {nome_produto} - {tamanho} para cada variação
  • Validações Avançadas: Ignora SKUs indisponíveis ou com preço inválido
  • 🖼️ URLs Completas: Conversão automática de URLs relativas e imagens
  • 📊 Testes Completos: Suite em test_sephora_parser.py com 10 validações
  • 📚 Documentação: Seção completa em PARSERS.md com casos de uso

v0.2.2 (2026-02-04)

  • BelezaNaWebHTMLParser Completo: Implementação finalizada com parse híbrido JSON+HTML
  • 🔍 Extração Avançada: Parse de data-event JSON embedded + fallback HTML estruturado
  • 🧹 Deduplicação por SKU: Remove ~430 produtos repetidos → 36 únicos (carrosséis)
  • 🏷️ Preço Antigo: Extração automática de .item-price-max com parse_price
  • 🖼️ URLs Completas: Conversão automática de URLs relativas para absolutas
  • Performance: Parser otimizado com lxml (fallback html.parser)
  • Validações Robustas: Ignora produtos sem SKU/preço com logs detalhados
  • 🧪 Testes Completos: Suite de testes com validações de campos e estatísticas

v0.2.1 (2026-02-03)

  • 🏪 Parsers de Lojas: Maze API, Nike API e Beleza na Web HTML (inicial)
  • 🔍 Parser HTML: Extração de produtos de páginas HTML com BeautifulSoup
  • 🧹 Deduplicação Automática: Remove produtos duplicados por SKU
  • 🏭 Factory Pattern: Sistema extensível para adicionar novos parsers
  • 🎨 Type Hints Completos: Melhor experiência com IDEs e linters

v0.1.0 (2026-02-03)

  • ✨ Sistema de validação de preços com estratégias
  • 📊 Ajuste automático de período histórico
  • 🔇 Filtro de ruído de dados recentes
  • 📈 Análise de tendências com volatilidade
  • 🎯 Novos modelos tipados e enums

Veja o changelog completo no CLAUDE.md

📄 Licença

MIT - veja LICENSE para detalhes.

👥 Contribuindo

Contribuições são bem-vindas! Abra issues ou pull requests no repositório.

⭐ Agradecimentos

Desenvolvido para ajudar consumidores a identificar promoções reais vs falsas no e-commerce brasileiro.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

notify_utils-0.4.0.tar.gz (43.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

notify_utils-0.4.0-py3-none-any.whl (45.7 kB view details)

Uploaded Python 3

File details

Details for the file notify_utils-0.4.0.tar.gz.

File metadata

  • Download URL: notify_utils-0.4.0.tar.gz
  • Upload date:
  • Size: 43.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for notify_utils-0.4.0.tar.gz
Algorithm Hash digest
SHA256 a96df41c681ae08a3780497f5234c543d98a945a41320e8e5c1a5652aaec8391
MD5 c2969c19fc54b5a1e270d168d4f9890e
BLAKE2b-256 ebe053aeecdeb726b4948a57162607cb0da6c38bd84da93eb0045e7980a39078

See more details on using hashes here.

File details

Details for the file notify_utils-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: notify_utils-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 45.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for notify_utils-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7563c4a7917f2b68b71af6dfd326dd3c263ab5dd28c433246712f71d57fa4637
MD5 d3e27e59a1676a7211525ebcb4d866e2
BLAKE2b-256 ee7980babb40141f8cd67d6a25bce33dff2f0cab155d11cb41da17c14c755374

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page