Compteur de visites : ces robots qui exécutent le JavaScript
Le matin du 4 novembre 2026, le compteur de visites de VosPosts affichait un chiffre flatteur : 3 352 visiteurs « humains » en une journée, puis 2 272 de plus avant 1 heure du matin, pour un site qui tourne habituellement autour de 400 visites par jour. Aucun article n’avait été partagé, aucun lien n’était parti en viral. Il s’agissait tout simplement de robots, et notre compteur les prenait pour des lecteurs.
Ce qui suit raconte comment nous l’avons découvert, pourquoi la méthode classique « si le JavaScript tourne, c’est un humain » ne tient plus, et comment repérer ces faux visiteurs dans vos propres journaux de serveur.
Le piège : « le JavaScript a tourné, donc c’est un humain »
Beaucoup de compteurs maison, et c’était le cas du nôtre, reposent sur une idée simple : le serveur enregistre la page demandée, puis un petit script exécuté dans le navigateur envoie une seconde requête qui « certifie » la visite. Les robots d’autrefois se contentaient de télécharger le HTML sans exécuter quoi que ce soit : la seconde requête n’arrivait jamais, et ils restaient hors des statistiques.
Ce filtre est devenu une passoire. Aujourd’hui, une bonne partie des robots exécute le JavaScript comme un vrai navigateur :
- Les moteurs de recherche affichent les pages pour les comprendre : Googlebot utilise un Chromium à jour, et on croise aussi Baiduspider-render, Applebot, Bytespider (ByteDance) ou meta-webindexer.
- Le robot publicitaire d’AdSense (Mediapartners-Google) visite les pages pour analyser leur contenu.
- Les scrapers modernes pilotent de vrais navigateurs sans interface : Chrome en mode headless, Puppeteer, Playwright, ou des moteurs plus légers comme Lightpanda, conçus pour l’automatisation et les agents d’IA.
Pour un compteur basé sur l’exécution du script, tous ces visiteurs sont indiscernables d’un lecteur. Le plus troublant, c’est que le problème ne date pas de l’attaque : en reprenant un jour parfaitement normal, le 3 novembre, nous avons constaté que 446 des 621 visites comptées comme humaines venaient en réalité de robots. Plus de sept visites sur dix.
Les signes d’un scraper à navigateur sans interface
Le pic du 4 novembre portait toutes les marques d’un scraping organisé. Pris isolément, aucun de ces indices ne prouve rien ; réunis, ils ne laissent guère de doute.
Une adresse IP différente à chaque page
Chaque page était demandée depuis une IP différente, réparties dans le monde entier. C’est la signature des proxys résidentiels : des réseaux qui font passer les requêtes par des connexions de particuliers, souvent à leur insu. Conséquence directe : bloquer des adresses IP ne sert à rien, il y en a des milliers et ce sont celles de vrais foyers.
Des navigateurs périmés depuis des années
Les user-agents tournaient en boucle sur une petite liste : Chrome 118 à 120, Firefox 120 et 121, Edge 119 et 120. Ces versions datent de fin 2023. Or Chrome et Firefox se mettent à jour seuls environ toutes les quatre semaines : nos vrais lecteurs, eux, arrivaient avec Chrome 148 à 156. Un visiteur qui se présente avec un navigateur de trois ans, ça existe, mais des milliers en une nuit, c’est une liste de user-agents recopiée une fois pour toutes dans un outil de scraping.
Au milieu de cette rotation apparaissait d’ailleurs, sans aucun déguisement, Lightpanda/1.0.
Un comportement trop régulier
- uniquement des ordinateurs de bureau, aucun mobile, alors que la majorité du trafic réel est sur téléphone ;
- aucun référent : personne n’arrivait depuis Google, un réseau social ou un autre site ;
- 2 340 recherches distinctes lancées dans le moteur interne du site, pour aspirer le plus de pages possible ;
- 24 772 requêtes sur la journée, soit 42 % de tout le trafic du serveur.
Le risque caché : les publicités
Un navigateur sans interface exécute tout, y compris le chargement des emplacements publicitaires : ce jour-là, nos blocs de pub ont été chargés 2 939 fois par le robot. Pour un éditeur AdSense, c’est un vrai sujet : des affichages générés par des robots relèvent du trafic invalide, que Google déduit des revenus et qui peut, s’il se répète, mettre le compte en difficulté. Un compteur gonflé n’est donc pas qu’une question d’ego.
Repérer ces robots dans vos journaux
Les journaux d’accès d’Apache ou de Nginx, au format « combined », contiennent tout ce qu’il faut. Quelques commandes suffisent à faire le tri. D’abord, les user-agents les plus fréquents :
awk -F'"' '{print $6}' access.log | sort | uniq -c | sort -rn | head -30Ensuite, la répartition des versions de Chrome. Sur un site normal, l’essentiel se concentre sur les quatre ou cinq dernières versions ; un gros paquet sur des versions anciennes saute aux yeux :
grep -oE 'Chrome/[0-9]+' access.log | sort | uniq -c | sort -t/ -k2 -nLe volume par heure permet de dater précisément le début et la fin d’une vague :
awk '{print substr($4, 2, 14)}' access.log | sort | uniq -cEnfin, pour une signature suspecte, comparez le nombre de requêtes au nombre d’IP distinctes. Si les deux chiffres sont presque égaux, vous tenez votre réseau de proxys :
grep -c 'Chrome/119.0.0.0' access.log
grep 'Chrome/119.0.0.0' access.log | awk '{print $1}' | sort -u | wc -lUn détail utile : depuis 2022, Chrome n’envoie plus que son numéro de version principal, suivi de .0.0.0. La forme Chrome/119.0.0.0 est donc normale ; c’est le chiffre 119 qui trahit le robot.
Ce que nous avons mis en place
Ne plus compter, sans bloquer
Premier niveau : le compteur décide, côté serveur, si la visite mérite d’être comptée. Une visite n’est plus enregistrée comme humaine si le user-agent est vide, s’il déclare un robot (bot, spider, crawler, outils HTTP comme curl ou Python, navigateurs sans interface), ou s’il annonce un Chrome ou un Firefox de plus de deux ans et demi. Le seuil se recalcule avec la date, pour ne jamais avoir à retoucher un numéro de version :
$jours = (time() - mktime(0, 0, 0, 12, 5, 2023)) / 86400; // Chrome 120, décembre 2023
$version_actuelle = 120 + (int)floor($jours / 28); // une version toutes les 4 semaines
if (preg_match('/Chrome/(d+)./', $ua, $m) && (int)$m[1] < $version_actuelle - 32) {
return true; // navigateur trop ancien pour être un lecteur réel
}Un garde-fou important : un utilisateur connecté à son compte est toujours compté, quel que soit son navigateur. Le filtre vise les inconnus, pas les membres fidèles qui ont oublié de mettre à jour un vieux poste.
Refuser le scraper, laisser passer les moteurs
Second niveau, plus offensif : le serveur répond désormais une erreur 403 aux signatures du scraper, avec une exception explicite pour les robots légitimes. En Apache, cela tient en quelques lignes :
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} (Lightpanda|HeadlessChrome) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} Chrome/1(18|19|20).0.0.0 [OR]
RewriteCond %{HTTP_USER_AGENT} Firefox/12[01].
RewriteCond %{HTTP_USER_AGENT} !(bot|spider|crawl|google|bing|facebook) [NC]
RewriteRule ^ - [F]Les trois premières conditions sont reliées par [OR], la dernière s’y ajoute par un « et » implicite : on bloque l’une des signatures, sauf si le user-agent se réclame d’un moteur ou d’un réseau social. Après la mise en place, nous avons vérifié les deux côtés : le scraper reçoit bien sa 403, tandis qu’un Chrome récent, un iPhone, Googlebot, Bingbot et le robot AdSense obtiennent toujours leur page.
Bloquer Googlebot par erreur peut coûter bien plus cher qu’un compteur gonflé. Testez chaque règle avec les user-agents des moteurs avant de la laisser en production.
Les limites à garder en tête
Un user-agent se falsifie en une ligne. Le jour où ce scraper annoncera un Chrome 155, ces règles ne le verront plus. Ce n’est pas une protection définitive, c’est une hygiène : elle élimine les robots paresseux, qui sont la grande majorité, et rend les chiffres à nouveau lisibles. Pour aller plus loin, il faut croiser plusieurs signaux (absence de référent, une page par IP, aucun mouvement de souris ni défilement) ou passer par un service spécialisé dans la détection des robots.
La vraie leçon est ailleurs : un compteur qui ne ment qu’une fois par an, lors d’un pic spectaculaire, ment probablement aussi tous les autres jours, plus discrètement. Si vous n’avez jamais regardé vos journaux d’accès, prenez dix minutes pour lancer les commandes ci-dessus sur une journée ordinaire. Le résultat risque de vous surprendre.
French
German
English
Spanish
Hindi
Italian
Japanese
Korean
Norwegian
Chinese


