← Projetos
Concluído

DealHunter — comparador de preços de jogos

Um comparador de preços que integra Steam, Epic, GOG e outras fontes, normaliza as ofertas em BRL e monitora jogos da wishlist.

  • Python
  • Streamlit
  • HTTPX
  • Discord
8 min de leitura

Comecei esse projeto enquanto estudava consumo de APIs com Python e HTTPX. A primeira versão era bem simples: consultar uma API e mostrar algumas promoções no terminal.

Conforme fui adicionando Steam, Epic, GOG e CheapShark, apareceu um problema mais interessante: cada fonte entrega os dados de um jeito diferente.

Preço em dólar em uma, real em outra, valores em centavos, nomes diferentes para o mesmo campo e até resultados que parecem ser o jogo procurado, mas na verdade são DLCs, demos ou trilhas sonoras.

Foi daí que saiu o DealHunter.

Hoje ele consulta diferentes fontes, padroniza as ofertas e permite comparar preços em reais, encontrar jogos gratuitos e acompanhar uma wishlist.

Demo · Código no GitHub

O uso é livre: quem só quer ver promoção entra na demo; quem quer bot aponta o webhook do Discord. Confira o preço no site da loja antes de comprar — API pública pode atrasar ou divergir.

O que ele faz

Quatro funções principais:

  • buscar um jogo e comparar as ofertas encontradas;
  • listar promoções e jogos gratuitos;
  • salvar jogos em uma wishlist com preço desejado;
  • enviar um alerta pelo Discord quando uma oferta atingir o preço ou desconto configurado.

A interface foi feita em Streamlit. A parte de integração e tratamento dos dados fica em src/dealhunter/. O app.py fica responsável principalmente pela tela.

De várias APIs para um formato só

Essa foi a parte mais interessante do projeto.

Steam, Epic, GOG e CheapShark não possuem um formato comum. Então, antes de qualquer resultado chegar à interface, transformo as respostas em uma estrutura padronizada: título, loja, preço atual, preço normal, moeda, desconto e link.

Steam ──────┐
Epic ───────┤
GOG ────────┼──→ HTTPX → normalização → DealHunter
CheapShark ─┘                         ├── Streamlit
                                      └── Discord

Isso também deixou cada integração independente. Se eu precisar alterar a forma como os dados da Epic são tratados, por exemplo, não preciso mexer na interface inteira.

O problema do câmbio

O CheapShark retorna preços em dólar, enquanto outras fontes já conseguem fornecer preços em real. Para comparar as ofertas, implementei a conversão USD → BRL.

No começo eu dependia de uma única API de câmbio. Funcionava localmente, mas no deploy começaram a aparecer respostas 403 e 429.

Em vez de deixar a aplicação quebrar, passei a consultar fontes alternativas:

AwesomeAPI
    ↓ falhou
currency-api
    ↓ falhou
Frankfurter

Também coloquei cache na cotação para não fazer uma nova requisição toda vez que alguém interage com a página.

Foi a parte em que mais aprendi sobre integração com APIs externas: uma API funcionar no meu computador não significa que ela vai estar disponível sempre ou se comportar igual em produção.

Comparar pelo nome também deu trabalho

Pesquisar um jogo pode retornar:

Resident Evil 4
Resident Evil 4 Demo
Resident Evil 4 Soundtrack
Resident Evil 4 - DLC

Se eu simplesmente pegasse o primeiro resultado ou comparasse strings sem tratamento, o DealHunter poderia mostrar uma oferta errada.

Por isso adicionei normalização dos títulos, filtros para alguns tipos de conteúdo e deduplicação por jogo e loja.

Não resolve todos os casos possíveis, mas reduziu bastante os falsos resultados durante os testes.

Wishlist e histórico

A wishlist permite definir um preço desejado para um jogo. Quando o preço encontrado atende à condição configurada, o DealHunter pode enviar uma mensagem para um webhook do Discord.

Também mantenho um histórico simples em CSV. Isso registra as consultas sem precisar colocar um banco de dados no projeto só por colocar.

A persistência é local, então existe uma limitação: o armazenamento do Streamlit Community Cloud é efêmero. Um redeploy pode apagar wishlist e histórico.

Para a proposta atual isso é aceitável. Se a aplicação crescer para vários usuários, essa provavelmente será uma das primeiras partes que vou substituir.

O que eu pratiquei

Python, HTTPX, APIs REST, tratamento de JSON, integração de fontes, normalização, tratamento de erros, fallback, persistência simples, Streamlit e webhooks.

A parte que mais gostei foi pegar fontes que não foram feitas para trabalhar juntas e criar uma estrutura comum para consumir esses dados.

O projeto começou como exercício de HTTPX e acabou virando uma aplicação que eu realmente consigo usar.