# Stratégie de découverte continue — écosystème ecommerce québécois Objectif : maintenir et faire croître en continu le registre de boutiques qui alimente Fabri-Ka (`data/stores.json`), au-delà de la récolte initiale. La stratégie est entièrement codée dans `scripts/` et rejouable. ## Le pipeline (implémenté) ``` Annuaires sources (certifications, associations, marques régionales) ↓ scripts/harvest.py — sitemaps/API/pagination → data/raw/.jsonl Extraction des liens sortants + signaux (nom, postal, téléphone, région) ↓ scripts/aggregate.py — normalisation domaine + dédup + provenance Candidats uniques (data/enriched/candidates.jsonl) ↓ scripts/verify.py — fetch page d'accueil (cache data/verify_cache/) Détection ecommerce (plateforme + endpoint catalogue public + panier) + vérification localisation QC (code postal G/H/J, indicatifs 418/514/450/819/…, TLD .quebec, mentions, wording « fabriqué au Québec ») ↓ scripts/build_registry.py — classification origine A–E avec évidence Registre canonique (data/stores.json) ↓ fabrika/ingest.py — connecteurs par plateforme, catalogue complet Base produits (data/fabrika.db, diff par hash, désactivation avec délai de grâce) ↓ récursion : nouveaux liens « nos détaillants / partenaires » → harvest ``` ## Principes qui ont le plus rapporté 1. **Sources à haut levier d'abord.** Une certification provinciale (Aliments du Québec : 1 001 entreprises ; Les Produits du Québec : 339) vaut des centaines de recherches manuelles, et fournit en prime une **preuve d'origine**. 2. **Sitemaps avant scraping.** 80 % des annuaires québécois sont des WordPress ; leurs sitemaps exposent directement les fiches membres (`/entreprises/*`, `/createurs/*`, `/membre/*`…). Coût : une requête XML. 3. **API cachées des cartes interactives.** Les répertoires « carte » (WP Google Maps, FacetWP, Storepoint) ont presque toujours un endpoint JSON public (ex. AMBQ : `/wp-json/wpgmza/v1/markers` → 328 adresses complètes). 4. **Marketplaces locales = listes de marques.** Signé Local et Boutique Métiers d'art exposent leurs vendeurs via l'endpoint Shopify public `products.json` (champ `vendor`) : 240 + 89 marques québécoises d'un coup. 5. **Redirections affiliées à résoudre.** Les répertoires-cadeaux passent par des trackers (affiliationfocus) : suivre la redirection donne le vrai domaine. 6. **Maillage régional.** Chaque région a sa marque agroalimentaire avec annuaire (Zone Boréale, Gaspésie Gourmande, Croquez Outaouais, Goûtez-y!, Arrêts Gourmands, Créateurs de saveurs, Laurentides j'en mange, Le Goût de la Côte-Nord…) — c'est LE correctif des angles morts hors Montréal/Québec. 7. **Balayage moteur × (catégorie × région)** pour la longue traîne : ~100 requêtes FR bien construites ont ajouté ~150 domaines absents de tout annuaire. ## Boucle d'exploitation continue (recommandée) | Fréquence | Action | Commande | |---|---|---| | 6 h | Resync des catalogues produits (déjà en prod) | `run.py watch 360` (PM2) | | Hebdo | Re-harvest des annuaires sources + delta verify | `harvest.py && aggregate.py && verify.py && build_registry.py` | | Hebdo | Retry des boutiques en erreur (429/timeout) | relance auto par le watcher | | Mensuel | Balayage recherche nouvelles requêtes (catégorie × région × « nouveau ») | agents de recherche | | Mensuel | Résolution nom→domaine des marques sans site connu (signelocal/BMAQ vendors) | recherche ciblée | | Trimestriel | Revue des sources mortes/nouvelles (marchés de Noël, salons, expos) | scouting | ## Détection par l'infrastructure ecommerce - **Shopify** : `/products.json` public = signal ET connecteur. ⚠️ limite de débit par IP partagée entre toutes les boutiques Shopify + fingerprinting TLS (python-requests se fait bloquer sous volume, `curl` passe) → throttle global 0,7 s/req et transport curl. - **WooCommerce** : `/wp-json/wc/store/v1/products` (Store API publique) — la moitié des boutiques QC détectées ; certaines la désactivent (fallback : rendu Firecrawl). - **Squarespace** : `?format=json` sur les pages collection. - **Wix** (125 détectées) : pas d'endpoint catalogue public simple — **connecteur à écrire** (API `wixstores` ou rendu Firecrawl). Plus gros stock non connecté. - Recherche inversée possible (non exploitée encore) : requêtes `site:myshopify.com` + mots QC, certificats CT logs, et listes publiques de domaines .quebec. ## Angles morts connus (et comment les combler) 1. **Artisans CMAQ (~1 000)** : répertoire en session JS — utiliser Firecrawl/rendu navigateur sur `repertoire_artisan.php`, ou OCR du catalogue du Salon des métiers d'art. 2. **Manufacturiers industriels vente directe** : absents des annuaires grand public. Pistes : successeur d'ICRIQ, répertoire STIQ, liste Investissement Québec « Achetons québécois », annuaires de zones industrielles/parcs technos. 3. **Nord-du-Québec** : quasi vide en ecommerce alimentaire ; couvrir via artisanat autochtone (coops cries/inuites : Wachiya, boutiques de pourvoiries). 4. **Boutiques sans annuaire ni SEO** (Instagram-only) : exiger un site web est un biais assumé du produit ; suivre quand même les liens Linktree/Instagram lors des balayages. 5. **Vendeurs Etsy québécois** : ToS d'Etsy interdit le scraping ; alternative = les artisans y affichant leur site propre finissent par apparaître via les salons/marchés récoltés. 6. **Fermes en circuit court** (paniers ASC) : le Réseau des fermiers·ères de famille (fermierdefamille.ca) a un répertoire à intégrer. ## Mesure de couverture À chaque itération, `aggregate.py` imprime les domaines uniques par source ; suivre la courbe des **nouveaux domaines par itération** (voir research_report.md). Critère d'arrêt d'une source : <5 % de nouveauté sur deux passes consécutives.