seo-collect — Collecteur de données SEO
Premier maillon du pipeline d'audit. Récupère toutes les données brutes depuis les sources et les range dans la réserve mutualisée du client (clients/<slug>/data/). Tous les skills d'analyse lisent ensuite cette réserve — ils ne requêtent JAMAIS les sources directement.
Ce qu'il collecte
| Source | Outil | Sortie dans la réserve | Indispensable |
|---|---|---|---|
| Crawl technique du site | DataForSEO OnPage API | data/crawl/<date>/{raw,pivot}.json |
Oui |
| Search & indexation | Google Search Console (gsc-mcp) | data/gsc/<date>/data.json |
Oui (simulé en démo) |
| Baseline domaine | DataForSEO Labs | data/dataforseo/<date>/baseline.json |
Si DFS dispo |
| Contenu propre des pages | crawl4ai (self-host) | data/content/<date>/*.md |
À la demande (audit contenu/GEO) |
Principe de fraîcheur (anti-recrawl)
Avant de (re)collecter, le skill teste la fraîcheur de chaque type via resolve_client.py (is_fresh). Si la donnée est encore fraîche (seuils dans client.json.data_freshness_days), il ne recollecte pas — économie de temps et de coûts API du client. --force pour forcer.
Détection de changement fine (V2) : comparer le lastmod du sitemap pour ne re-crawler que les URLs modifiées. Pour le MVP : fraîcheur par date suffit.
Procédure
- Résoudre le client :
client.jsonviaseo-os/scripts/resolve_client.py(domaine, gsc_property, competitors, clés API du client). Le cadrage (business_type, language, objectif, competitors) vient du formulaire d'onboarding rempli par le client (seo-os/references/onboarding-form.md), qui est la source de vérité duclient.json. Les concurrents sont fournis (trackés / SERP), jamais auto-détectés par similarité de mots-clés. Sicompetitorsest vide → revenir au client, ne pas deviner. - Crawl technique :
seo/dataforseo-onpage/run_crawl.py <slug>→ déposedata/crawl/<date>/. (Déjà construit et testé. Utilise les clés DataForSEO du client.) - GSC : appeler gsc-mcp avec
site_url = client.gsc_property. En démo (pas de GSC réel du prospect) → générateur d'inputs simulés. - DFS baseline : DataForSEO Labs (domain rank overview, ranked keywords) si clés dispo.
- Contenu (optionnel, si audit contenu/GEO demandé) : crawl4ai sur les pages clés → markdown propre dans
data/content/. - Manifeste de collecte : écrire
data/<date>/collect-manifest.json(quelles sources collectées, fraîcheur, comptes) pour traçabilité.
Lancement
Exécution (dès l'invocation) : chemin ABSOLU +
.envracine chargé.<slug>= argument. Pour un site Wix/JS, ajouter le rendu JS viarun_crawl.py --js(voir note).set -a; source .env; set +a python ./skills/seo-collect/scripts/collect.py <slug> --simulate-gsc
Options :
# Collecte complète (mode client)
python .../collect.py <slug>
# Forcer le recrawl même si frais
python .../collect.py <slug> --force
# Démo : GSC simulé (pas d'accès au Search Console du prospect)
python .../collect.py <slug> --simulate-gsc
# Site Wix/JS : crawl avec rendu JavaScript
python ./dataforseo-onpage/run_crawl.py <slug> --js --force
Contrat de sortie
Voir seo-os/references/data-contract.md. Le collecteur est le SEUL producteur de la réserve ; les skills d'analyse en sont les consommateurs. Respecter strictement les chemins et formats du contrat — c'est ce qui rend les skills interchangeables et portables sur Hermes.
Sur Hermes (cible)
Ce skill devient un profil-worker seo-collector, carte Kanban sans parent (premier maillon). Les skills d'analyse sont des cartes parents=[collect]. Le crawl4ai self-host sur le serveur Hermes du client fournit le scraper dédié.