Analyseur en ligne pour évaluer l'optimisation GEO (Generative Engine Optimization) d'une page web.
Créez un dossier sur votre serveur avec cette structure :
geo-audit/
├── index.html (Interface utilisateur)
├── audit.php (Backend d'analyse)
└── README.md (Ce fichier)
- PHP : 7.4 ou supérieur
- Extensions PHP :
curl(pour récupérer les pages)dom(pour parser le HTML)json(inclus par défaut)
- Serveur web : Apache, Nginx ou autre
Si vous utilisez Apache, créez un fichier .htaccess :
# Réécriture d'URL
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
# Forcer HTTPS (optionnel mais recommandé)
# RewriteCond %{HTTPS} off
# RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
# Sécurité
<Files "audit.php">
Order allow,deny
Allow from all
</Files>
# Compression GZIP
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/css application/javascript application/json
</IfModule>
# Cache
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/html "access plus 0 seconds"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
</IfModule>Si vous utilisez Nginx, ajoutez à votre configuration :
location / {
try_files $uri $uri/ /index.html;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
# Sécurité
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;Accédez à l'outil via : https://votre-domaine.com/geo-audit/
- Entrez l'URL de la page à analyser
- Sélectionnez le type de page (article, homepage, etc.)
- Cliquez sur "Lancer l'audit GEO"
- Consultez les résultats détaillés
- Organization : Détecte les entreprises/organisations
- Person : Détecte les personnes avec relations (worksFor, memberOf)
- Service : Détecte les services proposés
- Product : Détecte les produits
- LocalBusiness : Détecte les entreprises locales
- Images : Comptage total et vérification des attributs
alt - Vidéos : Détection (YouTube, Vimeo, hébergées)
- Audio : Détection des fichiers audio
- Médias GEO : Détection des blocs MediaGEO optimisés
- FAQ : Détection des FAQ (
<details>, Schema.org FAQPage) - Citations : Comptage des
<blockquote>et<cite> - JSON-LD : Vérification de la présence de Schema.org en JSON-LD
- Microdata : Détection du balisage microdata
- Title : Présence et longueur
- Description : Présence et longueur
- Open Graph : Vérification des balises OG
| Catégorie | Points max | Critères |
|---|---|---|
| Entités | 30 | Organization (+10), Person (+5 chacune), Total ≥3 (+10) |
| Médias | 25 | Images avec alt (+10), Vidéos (+10), Audio (+5) |
| Structure | 25 | FAQ ≥2 (+10), FAQSchema (+5), Citations (+5), JSON-LD (+5) |
| Métadonnées | 20 | Title (+5), Description (+5), Open Graph (+5), JSON-LD (+5) |
- 🟢 80-100 : Excellent - Optimisé pour les IA
- 🟡 50-79 : Bon - Améliorations possibles
- 🔴 0-49 : À améliorer - Travail nécessaire
Télécharge un fichier .csv avec toutes les métriques :
Métrique;Valeur
URL;https://example.com
Score GEO;85
Organizations;1
Persons;3
Images;12
Images avec alt;10
...Version PDF complète avec graphiques et recommandations détaillées.
Éditez audit.php, fonction calculateBreakdown() :
// Exemple : augmenter l'importance des FAQ
if ($audit['content']['faq'] >= 2) $breakdown['structure'] += 15; // au lieu de 10- Créez une fonction dans
audit.php:
function analyzeNewMetric($xpath) {
// Votre analyse
return $result;
}- Appelez-la dans
analyzeHTML():
$audit['newMetric'] = analyzeNewMetric($xpath);- Mettez à jour l'affichage dans
index.html
Cause : L'URL cible bloque les requêtes (Cloudflare, anti-bot) ou CURL n'est pas configuré
Solutions :
- Mode compatible : Cochez l'option "Utiliser un mode compatible" dans le formulaire
- Service de scraping : Configurez un service tiers (voir section ci-dessous)
- Mode HTML : Utilisez l'onglet "Analyser du HTML" en copiant le code source
- Vérifier CURL :
php -m | grep curl
# Installer CURL si absent (Ubuntu/Debian)
sudo apt-get install php-curl
sudo systemctl restart apache2Pour les sites protégés par Cloudflare ou des systèmes anti-bot, vous pouvez configurer un service de scraping tiers.
| Service | Description | Tarification |
|---|---|---|
| ScrapingBee | Excellent pour Cloudflare, JavaScript rendering | 1000 crédits gratuits |
| ScraperAPI | Rotation d'IP automatique, bon rapport qualité/prix | 1000 requêtes/mois gratuites |
| Browserless | Headless Chrome complet | Limité sans abonnement |
| ZenRows | Anti-bot avec IA | 1000 crédits gratuits |
- Créez un compte sur le service de votre choix
- Récupérez votre clé API
- Modifiez le fichier
scraping-config.json:
{
"service": "scrapingbee",
"api_key": "VOTRE_CLE_API",
"options": {
"render_js": "true",
"premium_proxy": "true",
"country_code": "fr"
}
}Une fois configuré :
- Option manuelle : Cochez "Utiliser un service de scraping tiers" dans le formulaire
- Automatique : Le service est utilisé en dernier recours si toutes les autres méthodes échouent
L'outil utilise plusieurs stratégies en cascade :
- Service de scraping (si demandé et configuré)
- Mode compatible avancé : Google Cache, Web Archive, Googlebot UA, Mobile UA
- Headers Chrome réalistes
- cURL basique
- file_get_contents
- Fallback service de scraping (si configuré mais non demandé)
Cause : JSON-LD mal formé sur la page cible
Solution : L'erreur est normale, le script continue l'analyse
Cause : Page trop lourde ou serveur lent
Solution : Augmentez le timeout dans audit.php :
curl_setopt($ch, CURLOPT_TIMEOUT, 60); // 60 secondes au lieu de 30Ajoutez un rate limiting dans audit.php :
session_start();
// Limite : 10 audits par heure
if (!isset($_SESSION['audit_count'])) {
$_SESSION['audit_count'] = 0;
$_SESSION['audit_reset'] = time() + 3600;
}
if (time() > $_SESSION['audit_reset']) {
$_SESSION['audit_count'] = 0;
$_SESSION['audit_reset'] = time() + 3600;
}
if ($_SESSION['audit_count'] >= 10) {
http_response_code(429);
echo json_encode(['error' => 'Limite atteinte, réessayez dans 1 heure']);
exit;
}
$_SESSION['audit_count']++;Le script valide déjà les URLs avec FILTER_VALIDATE_URL.
Pour plus de sécurité, ajoutez une whitelist de domaines :
$allowedDomains = ['example.com', 'monsite.fr'];
$domain = parse_url($url, PHP_URL_HOST);
if (!in_array($domain, $allowedDomains)) {
http_response_code(403);
echo json_encode(['error' => 'Domaine non autorisé']);
exit;
}MIT License - Libre d'utilisation et de modification
Erwan Tanguy - Ticoët
🌐 ticoet.fr
Pour toute question ou bug :
- 📧 Contact via ticoet.fr
- 🐛 Issues GitHub (si hébergé sur GitHub)
- Export PDF avec graphiques
- Analyse des performances (Core Web Vitals)
- Détection du fichier
llms.txt - Comparaison avec concurrents
- Historique des audits
- API REST pour intégrations
- Analyse multi-pages (site complet)
- Suggestions de contenu IA
- Monitoring automatique
- Alertes par email