# Fixtures Backmarket Ce dossier contient des fichiers HTML réels capturés depuis Backmarket.fr pour les tests. ## ⚠️ Note importante sur Backmarket Backmarket utilise une **protection anti-bot**: - HTTP simple retourne **403 Forbidden** - **Playwright est OBLIGATOIRE** pour récupérer le contenu - Temps de chargement: ~2-3 secondes ## Spécificité Backmarket Backmarket vend des **produits reconditionnés**: - Prix variable selon la **condition** (Correct, Bon, Excellent, etc.) - Chaque produit a plusieurs offres avec des états différents - Le prix extrait correspond à l'offre sélectionnée par défaut ## Fichiers ### backmarket_iphone15pro.html - **Produit**: iPhone 15 Pro (reconditionné) - **SKU**: iphone-15-pro - **URL**: https://www.backmarket.fr/fr-fr/p/iphone-15-pro - **Taille**: ~1.5 MB - **Date capture**: 2026-01-13 - **Prix capturé**: 571 EUR (prix de l'offre par défaut) - **Usage**: Test complet parsing smartphone reconditionné ## Structure HTML Backmarket ### JSON-LD Schema.org ✓ Backmarket utilise **JSON-LD structuré** (contrairement à Cdiscount): ```json { "@type": "Product", "name": "iPhone 15 Pro", "offers": { "@type": "Offer", "price": "571.00", "priceCurrency": "EUR" } } ``` ### Sélecteurs identifiés #### Titre ```css h1.heading-1 ``` Classes stables, simple et propre. #### Prix Priorité: **JSON-LD** (source la plus fiable) Fallback: `div[data-test='price']` #### Images ```css img[alt] ``` URLs CDN: `https://d2e6ccujb3mkqf.cloudfront.net/...` #### SKU Extraction depuis l'URL: ```regex /p/([a-z0-9-]+) ``` Exemple: `/p/iphone-15-pro` → SKU = "iphone-15-pro" #### Condition (État du reconditionné) ```css button[data-test='condition-button'] div[class*='condition'] ``` Valeurs possibles: Correct, Bon, Très bon, Excellent, Comme neuf ## Comparaison avec autres stores | Aspect | Amazon | Cdiscount | Backmarket | |--------|--------|-----------|------------| | **Anti-bot** | Faible | Fort | Fort | | **Méthode** | HTTP OK | Playwright | Playwright | | **JSON-LD** | Partiel | ✗ Non | ✓ Oui (complet) | | **Sélecteurs** | Stables (IDs) | Instables | Stables (classes) | | **SKU format** | `/dp/{ASIN}` | `/f-{cat}-{SKU}` | `/p/{slug}` | | **Particularité** | - | Prix dynamiques | Reconditionné (condition) | ## Utilisation dans les tests ```python @pytest.fixture def backmarket_fixture_iphone15pro(): fixture_path = Path(__file__).parent.parent.parent / \ "pricewatch/app/stores/backmarket/fixtures/backmarket_iphone15pro.html" with open(fixture_path, "r", encoding="utf-8") as f: return f.read() def test_parse_real_fixture(store, backmarket_fixture_iphone15pro): url = "https://www.backmarket.fr/fr-fr/p/iphone-15-pro" snapshot = store.parse(backmarket_fixture_iphone15pro, url) assert snapshot.title == "iPhone 15 Pro" assert snapshot.price == 571.0 assert snapshot.reference == "iphone-15-pro" assert snapshot.currency == "EUR" ``` ## Points d'attention pour les tests 1. **JSON-LD prioritaire** - Le prix vient du JSON-LD, pas du HTML visible 2. **Prix variable** - Change selon la condition sélectionnée 3. **Ne pas tester le prix exact** - Il varie avec les offres disponibles 4. **Tester le format** et la présence des données 5. Backmarket = **produits reconditionnés** uniquement ## Comment capturer une nouvelle fixture ```python from pricewatch.app.scraping.pw_fetch import fetch_playwright url = "https://www.backmarket.fr/fr-fr/p/..." result = fetch_playwright(url, headless=True, timeout_ms=60000) if result.success: with open("fixture.html", "w", encoding="utf-8") as f: f.write(result.html) ``` ⚠️ **N'utilisez JAMAIS** `fetch_http()` pour Backmarket - cela retournera 403! ## Avantages de Backmarket ✓ **JSON-LD structuré** → Parsing très fiable ✓ **Classes CSS stables** → Moins de casse que Cdiscount ✓ **URL propre** → SKU facile à extraire ✓ **Schema.org complet** → Prix, nom, images dans JSON ## Inconvénients ✗ **Protection anti-bot** → Playwright obligatoire (lent) ✗ **Prix multiples** → Un produit = plusieurs offres selon état ✗ **Stock complexe** → Dépend de l'offre et de la condition