Files
scrap/pricewatch/app/stores/cdiscount/fixtures
2026-01-13 19:49:04 +01:00
..
2026-01-13 19:49:04 +01:00

Fixtures Cdiscount

Ce dossier contient des fichiers HTML réels capturés depuis Cdiscount.com pour les tests.

⚠️ Note importante sur Cdiscount

Cdiscount utilise une protection anti-bot forte (Cloudflare/Baleen):

  • HTTP simple retourne une page de protection JavaScript (~14 KB)
  • Playwright est OBLIGATOIRE pour récupérer le vrai contenu
  • Temps de chargement: ~2-3 secondes

Fichiers

cdiscount_tuf608umrv004_pw.html

Différences avec Amazon

Aspect Amazon Cdiscount
Anti-bot Faible (HTTP OK) ✗ Fort (Playwright requis)
Sélecteurs Stables (IDs) Instables (classes générées)
Structure #productTitle, .a-price data-e2e="title", classes dynamiques
Prix 3 parties (whole+fraction+symbol) Texte direct "1499,99 €"
Référence ASIN dans URL /dp/{ASIN} SKU dans URL /f-{cat}-{SKU}.html
Catégorie Breadcrumb HTML Dans l'URL path
Specs Tables HTML Peut être dans onglets cachés

Sélecteurs identifiés

Titre

h1[data-e2e="title"]

Exemple: "PC Portable Gamer ASUS TUF Gaming A16 | Sans Windows - 16" WUXGA..."

Prix

Classes CSS instables. Utiliser regex sur le texte:

(\d+[,\.]\d+)\s*€

Exemple: "1199,99 €" → 1199.99

Images

img[alt]

Filtrer celles dont alt contient le titre du produit. Format URL: https://www.cdiscount.com/pdt2/0/0/4/{num}/700x700/{sku}/rw/...

SKU

Extraction depuis l'URL:

/f-\d+-([a-z0-9]+)\.html

Groupe 1 = SKU (ex: tuf608umrv004)

Catégorie

Extraction depuis l'URL path:

/informatique/ordinateurs-pc-portables/...
  ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^
  catégorie1 catégorie2

Utilisation dans les tests

@pytest.fixture
def cdiscount_fixture_tuf608umrv004():
    fixture_path = Path(__file__).parent.parent.parent / \
        "pricewatch/app/stores/cdiscount/fixtures/cdiscount_tuf608umrv004_pw.html"
    with open(fixture_path, "r", encoding="utf-8") as f:
        return f.read()

def test_parse_real_fixture(store, cdiscount_fixture_tuf608umrv004):
    url = "https://www.cdiscount.com/informatique/.../f-10709-tuf608umrv004.html"
    snapshot = store.parse(cdiscount_fixture_tuf608umrv004, url)

    assert snapshot.title is not None
    assert "ASUS" in snapshot.title
    assert snapshot.price == 1199.99
    assert snapshot.reference == "tuf608umrv004"

Points d'attention pour les tests

  1. Ne pas tester les valeurs exactes (prix, nombre d'avis) car elles changent
  2. Tester le format et la présence des données
  3. Prévoir des fallbacks pour chaque champ (sélecteurs instables)
  4. Les classes CSS peuvent changer à tout moment
  5. Utiliser data-e2e attributes quand disponibles (plus stables)
  6. Parser le prix par regex plutôt que par sélecteurs CSS

Comment capturer une nouvelle fixture

from pricewatch.app.scraping.pw_fetch import fetch_playwright

url = "https://www.cdiscount.com/..."
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 Cdiscount - cela ne fonctionnera pas!