chore: sync project files

This commit is contained in:
Gilles Soulier
2026-01-13 19:49:04 +01:00
parent 53f8227941
commit ecda149a4b
149 changed files with 65272 additions and 1 deletions

View File

@@ -0,0 +1,143 @@
# 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