Fixtures AliExpress
Ce dossier contient des fichiers HTML réels capturés depuis AliExpress pour les tests.
⚠️ Note importante sur AliExpress
AliExpress utilise un rendu client-side (SPA React/Vue):
- HTTP simple retourne HTML minimal (75KB sans contenu)
- Playwright est OBLIGATOIRE avec attente (~3s)
- Attendre le sélecteur
.product-titlepour obtenir les données - Données chargées via AJAX après le render initial
Spécificité AliExpress
AliExpress est un marketplace chinois avec des particularités:
- Pas de JSON-LD schema.org
- Prix: Extrait par regex (aucun sélecteur CSS stable)
- Images: Extraites depuis
window._d_c_.DCData.imagePathList(JSON embarqué) - Classes CSS: Générées aléatoirement (hachées) → TRÈS instables
- SKU: ID numérique long (13 chiffres) depuis l'URL
Fichiers
aliexpress_1005007187023722.html
- Produit: Samsung serveur DDR4 mémoire Ram ECC
- SKU: 1005007187023722
- URL: https://fr.aliexpress.com/item/1005007187023722.html
- Taille: 378 KB (rendu complet)
- Date capture: 2026-01-13
- Méthode: Playwright avec wait_for_selector='.product-title'
- Prix capturé: 136,69 EUR
- Usage: Test complet parsing produit électronique
Structure HTML AliExpress
JSON-LD Schema.org ✗
AliExpress n'utilise PAS JSON-LD (contrairement à Backmarket).
Données embarquées ✓
AliExpress embarque les données dans des variables JavaScript:
window._d_c_.DCData = {
"imagePathList": ["https://ae01.alicdn.com/kf/..."],
"summImagePathList": ["https://ae01.alicdn.com/kf/..."],
"i18nMap": {...},
"extParams": {...}
}
Sélecteurs identifiés
Titre
h1 /* Apparaît après AJAX */
meta[property="og:title"] /* Fallback dans meta tags */
Le h1 n'existe PAS dans le HTML initial, il est ajouté dynamiquement.
Prix
⚠️ AUCUN SÉLECTEUR CSS STABLE - Utiliser regex:
([0-9]+[.,][0-9]{2})\s*€ /* Prix avant € */
€\s*([0-9]+[.,][0-9]{2}) /* € avant prix */
Images
Priorité: window.d_c.DCData.imagePathList
Fallback: meta[property="og:image"]
URLs CDN: https://ae01.alicdn.com/kf/...
SKU
Extraction depuis l'URL:
/item/(\d+)\.html
Exemple: /item/1005007187023722.html → SKU = "1005007187023722"
Stock
Chercher bouton "Add to cart" / "Ajouter au panier"
button[class*='add-to-cart']
Comparaison avec autres stores
| Aspect | Amazon | Cdiscount | Backmarket | AliExpress |
|---|---|---|---|---|
| Anti-bot | Faible | Fort | Fort | Moyen |
| Méthode | HTTP OK | Playwright | Playwright | Playwright |
| JSON-LD | Partiel | ✗ Non | ✓ Oui | ✗ Non |
| Sélecteurs | Stables (IDs) | Instables | Stables | Très instables |
| SKU format | /dp/{ASIN} |
/f-{cat}-{SKU} |
/p/{slug} |
/item/{ID}.html |
| Prix extraction | CSS | CSS/Regex | JSON-LD | Regex uniquement |
| Rendu | Server-side | Server-side | Server-side | Client-side (SPA) |
| Particularité | - | Prix dynamiques | Reconditionné | SPA React/Vue |
Utilisation dans les tests
@pytest.fixture
def aliexpress_fixture_samsung():
fixture_path = Path(__file__).parent.parent.parent / \
"pricewatch/app/stores/aliexpress/fixtures/aliexpress_1005007187023722.html"
with open(fixture_path, "r", encoding="utf-8") as f:
return f.read()
def test_parse_real_fixture(store, aliexpress_fixture_samsung):
url = "https://fr.aliexpress.com/item/1005007187023722.html"
snapshot = store.parse(aliexpress_fixture_samsung, url)
assert snapshot.title.startswith("Samsung serveur DDR4")
assert snapshot.price == 136.69
assert snapshot.reference == "1005007187023722"
assert snapshot.currency == "EUR"
assert len(snapshot.images) >= 6
Points d'attention pour les tests
- HTML volumineux - 378KB pour une page (SPA chargée)
- Prix instable - Peut changer selon promo/devise
- Ne pas tester le prix exact - Tester le format et la présence
- Images multiples - Toujours 6+ images par produit
- Titre long - Souvent 100-150 caractères
- Stock variable - Peut changer rapidement
Comment capturer une nouvelle fixture
from pricewatch.app.scraping.pw_fetch import fetch_playwright
url = "https://fr.aliexpress.com/item/..."
result = fetch_playwright(
url,
headless=True,
timeout_ms=15000,
wait_for_selector=".product-title" # IMPORTANT!
)
if result.success:
with open("fixture.html", "w", encoding="utf-8") as f:
f.write(result.html)
⚠️ N'utilisez PAS fetch_http() - il retourne un HTML minimal (75KB)!
⚠️ Utilisez TOUJOURS wait_for_selector=".product-title" avec Playwright!
Avantages de AliExpress
✓ HTTP fonctionne → Pas d'anti-bot fort (mais HTML vide) ✓ Données embarquées → DCData JSON avec images ✓ SKU simple → ID numérique depuis URL
Inconvénients
✗ SPA client-side → Playwright obligatoire avec wait (~3-5s) ✗ Pas de JSON-LD → Extraction moins fiable ✗ Prix par regex → Fragile, peut casser ✗ Classes CSS instables → Générées aléatoirement (hachées) ✗ Temps de chargement → 3-5s avec Playwright + wait ✗ Specs mal structurées → Souvent dans des onglets/modals