Metadata-Version: 2.4 Name: pricewatch Version: 0.1.0 Summary: Application Python de suivi de prix e-commerce (Amazon, Cdiscount, extensible) Author: PriceWatch Team Keywords: scraping,e-commerce,price-tracking,amazon,cdiscount Classifier: Development Status :: 3 - Alpha Classifier: Intended Audience :: Developers Classifier: Programming Language :: Python :: 3.12 Classifier: Topic :: Software Development :: Libraries :: Python Modules Requires-Python: >=3.12 Description-Content-Type: text/markdown Requires-Dist: typer[all]>=0.12.0 Requires-Dist: pydantic>=2.5.0 Requires-Dist: pydantic-settings>=2.1.0 Requires-Dist: requests>=2.31.0 Requires-Dist: httpx>=0.26.0 Requires-Dist: playwright>=1.41.0 Requires-Dist: beautifulsoup4>=4.12.0 Requires-Dist: lxml>=5.1.0 Requires-Dist: cssselect>=1.2.0 Requires-Dist: pyyaml>=6.0.1 Requires-Dist: python-dateutil>=2.8.2 Requires-Dist: sqlalchemy>=2.0.0 Requires-Dist: psycopg2-binary>=2.9.0 Requires-Dist: alembic>=1.13.0 Requires-Dist: python-dotenv>=1.0.0 Requires-Dist: redis>=5.0.0 Requires-Dist: rq>=1.15.0 Requires-Dist: rq-scheduler>=0.13.0 Requires-Dist: fastapi>=0.110.0 Requires-Dist: uvicorn>=0.27.0 Provides-Extra: dev Requires-Dist: pytest>=8.0.0; extra == "dev" Requires-Dist: pytest-cov>=4.1.0; extra == "dev" Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev" Requires-Dist: pytest-mock>=3.12.0; extra == "dev" Requires-Dist: ruff>=0.1.0; extra == "dev" Requires-Dist: black>=24.0.0; extra == "dev" Requires-Dist: mypy>=1.8.0; extra == "dev" Requires-Dist: types-requests>=2.31.0; extra == "dev" Requires-Dist: types-pyyaml>=6.0.0; extra == "dev" Requires-Dist: types-beautifulsoup4>=4.12.0; extra == "dev" # 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 ```bash # Cloner le dépôt git clone 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 ```bash # 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 ```bash # 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 ```bash # 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 ```bash # 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) ```bash # 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. ```bash export PW_API_TOKEN=change_me docker compose up -d api ``` Exemples: ```bash curl -H "Authorization: Bearer $PW_API_TOKEN" http://localhost:8000/products curl http://localhost:8000/health ``` ## Configuration (scrap_url.yaml) ```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 ```bash # 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 - [x] Base de données PostgreSQL - [x] 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