Gilles Soulier cf7c415e22 before claude
2026-01-17 13:40:26 +01:00
2026-01-17 13:40:26 +01:00
2026-01-17 13:40:26 +01:00
2026-01-17 13:40:26 +01:00
2026-01-14 21:54:55 +01:00
2026-01-13 19:49:04 +01:00
2026-01-17 13:40:26 +01:00
2026-01-17 13:40:26 +01:00
2026-01-17 13:40:26 +01:00
2026-01-17 13:40:26 +01:00
2026-01-14 21:54:55 +01:00
2026-01-14 21:54:55 +01:00
2026-01-14 21:54:55 +01:00
2026-01-13 19:49:04 +01:00
2026-01-14 21:54:55 +01:00
2026-01-13 19:49:04 +01:00
2026-01-13 19:49:04 +01:00
2026-01-13 19:49:04 +01:00
2026-01-14 21:54:55 +01:00
2026-01-13 19:49:04 +01:00
2026-01-13 19:49:04 +01:00
2026-01-17 13:40:26 +01:00
2026-01-14 21:54:55 +01:00
2026-01-13 19:49:04 +01:00
2026-01-13 19:49:04 +01:00
2026-01-13 19:49:04 +01:00
2026-01-17 13:40:26 +01:00
2026-01-14 21:54:55 +01:00
2026-01-14 21:54:55 +01:00
2026-01-14 21:54:55 +01:00
2026-01-17 13:40:26 +01:00
2026-01-14 21:54:55 +01:00
2026-01-17 13:40:26 +01:00
2026-01-13 19:49:04 +01:00
2026-01-14 21:54:55 +01:00
2026-01-14 21:54:55 +01:00
2026-01-14 21:54:55 +01:00
2026-01-13 19:49:04 +01:00
2026-01-14 21:54:55 +01:00
2026-01-13 19:49:04 +01:00
2026-01-14 21:54:55 +01:00
2026-01-14 21:54:55 +01:00
2026-01-14 21:54:55 +01:00
2026-01-13 19:49:04 +01:00
2026-01-13 19:49:04 +01:00
2026-01-13 19:49:04 +01:00
2026-01-13 19:49:04 +01:00
2026-01-13 19:49:04 +01:00
2026-01-13 19:49:04 +01:00
2026-01-13 19:49:04 +01:00
2026-01-14 21:54:55 +01:00

PriceWatch 🛒

Application Python de suivi de prix e-commerce (Amazon, Cdiscount, extensible).

Description

PriceWatch est une application CLI permettant de scraper et suivre les prix de produits sur différents sites e-commerce. L'application gère automatiquement la détection du site, la récupération des données (HTTP + fallback Playwright), et produit un historique exploitable.

Fonctionnalités

  • Scraping automatique avec détection du site marchand
  • Récupération multi-méthode (HTTP prioritaire, Playwright en fallback)
  • Support Amazon et Cdiscount (architecture extensible)
  • Extraction complète des données produit (prix, titre, images, specs, stock)
  • Pipeline YAML → JSON reproductible
  • Logging détaillé et mode debug
  • Tests pytest avec fixtures HTML

Prérequis

  • Python 3.12+
  • pip

Installation

# Cloner le dépôt
git clone <repository-url>
cd scrap

# Installer les dépendances
pip install -e .

# Installer les navigateurs Playwright
playwright install

Structure du projet

pricewatch/
├── app/
│   ├── core/              # Modèles et utilitaires centraux
│   │   ├── schema.py      # ProductSnapshot (modèle Pydantic)
│   │   ├── registry.py    # Détection automatique des stores
│   │   ├── io.py          # Lecture YAML / Écriture JSON
│   │   └── logging.py     # Configuration logging
│   ├── scraping/          # Méthodes de récupération
│   │   ├── http_fetch.py  # Récupération HTTP
│   │   └── pw_fetch.py    # Récupération Playwright
│   ├── stores/            # Parsers par site marchand
│   │   ├── base.py        # Classe abstraite BaseStore
│   │   ├── amazon/
│   │   │   ├── store.py
│   │   │   ├── selectors.yml
│   │   │   └── fixtures/
│   │   └── cdiscount/
│   │       ├── store.py
│   │       ├── selectors.yml
│   │       └── fixtures/
│   ├── db/                # Persistence SQLAlchemy (Phase 2)
│   │   ├── models.py
│   │   ├── connection.py
│   │   └── migrations/
│   ├── tasks/             # Jobs RQ (Phase 3)
│   │   ├── scrape.py
│   │   └── scheduler.py
│   └── cli/
│       └── main.py        # CLI Typer
├── tests/                 # Tests pytest
├── scraped/               # Fichiers de debug (HTML, screenshots)
├── scrap_url.yaml         # Configuration des URLs à scraper
└── scraped_store.json     # Résultat du scraping

Usage CLI

Pipeline complet

# Scraper toutes les URLs définies dans scrap_url.yaml
pricewatch run --yaml scrap_url.yaml --out scraped_store.json

# Avec debug
pricewatch run --yaml scrap_url.yaml --out scraped_store.json --debug

# Avec persistence DB
pricewatch run --yaml scrap_url.yaml --out scraped_store.json --save-db

Commandes utilitaires

# Détecter le store depuis une URL
pricewatch detect https://www.amazon.fr/dp/B08N5WRWNW

# Récupérer une page (HTTP)
pricewatch fetch https://www.amazon.fr/dp/B08N5WRWNW --http

# Récupérer une page (Playwright)
pricewatch fetch https://www.amazon.fr/dp/B08N5WRWNW --playwright

# Parser un fichier HTML avec un store spécifique
pricewatch parse amazon --in scraped/page.html

# Vérifier l'installation
pricewatch doctor

Commandes base de donnees

# Initialiser les tables
pricewatch init-db

# Generer une migration
pricewatch migrate "Initial schema"

# Appliquer les migrations
pricewatch upgrade

# Revenir en arriere
pricewatch downgrade -1

Commandes worker

# Lancer un worker RQ
pricewatch worker

# Enqueue un job immediat
pricewatch enqueue "https://example.com/product"

# Planifier un job recurrent
pricewatch schedule "https://example.com/product" --interval 24

Base de donnees (Phase 2)

# Lancer PostgreSQL + Redis en local
docker-compose up -d

# Exemple de configuration
cp .env.example .env

Guide de migration JSON -> DB: MIGRATION_GUIDE.md

API REST (Phase 3)

L'API est protegee par un token simple.

export PW_API_TOKEN=change_me
docker compose up -d api

Exemples:

curl -H "Authorization: Bearer $PW_API_TOKEN" http://localhost:8001/products
curl http://localhost:8001/health

Filtres (exemples rapides):

curl -H "Authorization: Bearer $PW_API_TOKEN" \\
  "http://localhost:8001/products?price_min=100&stock_status=in_stock"
curl -H "Authorization: Bearer $PW_API_TOKEN" \\
  "http://localhost:8001/products/1/prices?fetch_status=success&fetched_after=2026-01-14T00:00:00"
curl -H "Authorization: Bearer $PW_API_TOKEN" \\
  "http://localhost:8001/logs?fetch_status=failed&fetched_before=2026-01-15T00:00:00"

Exports (CSV/JSON):

curl -H "Authorization: Bearer $PW_API_TOKEN" \\
  "http://localhost:8001/products/export?format=csv"
curl -H "Authorization: Bearer $PW_API_TOKEN" \\
  "http://localhost:8001/logs/export?format=json"

CRUD (examples rapides):

curl -H "Authorization: Bearer $PW_API_TOKEN" -X POST http://localhost:8001/products \\
  -H "Content-Type: application/json" \\
  -d '{"source":"amazon","reference":"REF1","url":"https://example.com"}'

Webhooks (exemples rapides):

curl -H "Authorization: Bearer $PW_API_TOKEN" -X POST http://localhost:8001/webhooks \\
  -H "Content-Type: application/json" \\
  -d '{"event":"price_changed","url":"https://example.com/webhook","enabled":true}'
curl -H "Authorization: Bearer $PW_API_TOKEN" -X POST http://localhost:8001/webhooks/1/test

Web UI (Phase 4)

Interface Vue 3 dense avec themes Gruvbox/Monokai, header fixe, sidebar filtres, et split compare.

docker compose up -d frontend
# Acces: http://localhost:3000

Configuration (scrap_url.yaml)

urls:
  - "https://www.amazon.fr/dp/B08N5WRWNW"
  - "https://www.cdiscount.com/informatique/clavier-souris-webcam/example/f-1070123-example.html"

options:
  use_playwright: true    # Utiliser Playwright en fallback
  headful: false          # Mode headless (true = voir le navigateur)
  save_html: true         # Sauvegarder HTML pour debug
  save_screenshot: true   # Sauvegarder screenshot pour debug
  timeout_ms: 60000       # Timeout par page (ms)

Format de sortie (ProductSnapshot)

Chaque produit scraped est représenté par un objet ProductSnapshot contenant :

Métadonnées

  • source: Site d'origine (amazon, cdiscount, unknown)
  • url: URL canonique du produit
  • fetched_at: Date/heure de récupération (ISO 8601)

Données produit

  • title: Nom du produit
  • price: Prix (float ou null)
  • currency: Devise (EUR, USD, etc.)
  • shipping_cost: Frais de port (float ou null)
  • stock_status: Statut stock (in_stock, out_of_stock, unknown)
  • reference: Référence produit (ASIN pour Amazon, SKU pour autres)
  • images: Liste des URLs d'images
  • category: Catégorie du produit
  • specs: Caractéristiques techniques (dict clé/valeur)

Debug

  • debug.method: Méthode utilisée (http, playwright)
  • debug.errors: Liste des erreurs rencontrées
  • debug.notes: Notes techniques
  • debug.status: Statut de récupération (success, partial, failed)

Tests

# Lancer tous les tests
pytest

# Tests avec couverture
pytest --cov=pricewatch

# Tests d'un store spécifique
pytest tests/stores/amazon/
pytest tests/stores/cdiscount/

# Mode verbose
pytest -v

Architecture des stores

Chaque store implémente la classe abstraite BaseStore avec :

  • match(url) -> float: Score de correspondance (0.0 à 1.0)
  • canonicalize(url) -> str: Normalisation de l'URL
  • extract_reference(url) -> str: Extraction référence produit
  • fetch(url, method, options) -> str: Récupération HTML
  • parse(html, url) -> ProductSnapshot: Parsing vers modèle canonique

Les sélecteurs (XPath/CSS) sont externalisés dans selectors.yml pour faciliter la maintenance.

Ajouter un nouveau store

  1. Créer pricewatch/app/stores/nouveaustore/
  2. Créer store.py avec une classe héritant de BaseStore
  3. Créer selectors.yml avec les sélecteurs XPath/CSS
  4. Ajouter des fixtures HTML dans fixtures/
  5. Enregistrer le store dans le Registry
  6. Écrire les tests dans tests/stores/nouveaustore/

Gestion des erreurs

L'application est conçue pour être robuste face aux anti-bots :

  • 403 Forbidden : Fallback automatique vers Playwright
  • Captcha détecté : Logged dans debug.errors, statut failed
  • Timeout : Configurable, logged
  • Parsing échoué : ProductSnapshot partiel avec debug.status=partial

Aucune erreur ne doit crasher silencieusement : toutes sont loggées et tracées dans le ProductSnapshot.

Roadmap

Phase 1 : CLI (actuelle)

  • Pipeline YAML → JSON
  • Support Amazon + Cdiscount
  • Scraping HTTP + Playwright
  • Tests pytest

Phase 2 : Persistence

  • Base de données PostgreSQL
  • Migrations Alembic
  • Historique des prix

Phase 3 : Automation

  • Worker (Redis + RQ/Celery)
  • Planification quotidienne
  • Gestion de la queue

Phase 4 : Web UI

  • Interface web responsive
  • Dark theme (Gruvbox)
  • Graphiques historique prix
  • Gestion des alertes

Phase 5 : Alertes

  • Notifications baisse de prix
  • Notifications retour en stock
  • Webhooks/email

Développement

Règles

  • Python 3.12 obligatoire
  • Commentaires et discussions en français
  • Toute décision technique doit être justifiée (1-3 phrases)
  • Pas d'optimisation prématurée
  • Logging systématique (méthode, durée, erreurs)
  • Tests obligatoires pour chaque store

Documentation

  • README.md : Ce fichier
  • TODO.md : Liste des tâches priorisées
  • CHANGELOG.md : Journal des modifications
  • CLAUDE.md : Guide pour Claude Code

License

À définir

Auteur

À définir

Description
No description provided
Readme 28 MiB
Languages
HTML 88.7%
Python 9.9%
Vue 1.2%
CSS 0.1%