SAVOIR SI LE VISITEUR EST UN ROBOT D'UN MOTEUR DE RECHERCHE

cs_Astalavista Messages postés 192 Date d'inscription lundi 24 décembre 2001 Statut Membre Dernière intervention 3 février 2010 - 29 avril 2007 à 02:48
Clad49 Messages postés 265 Date d'inscription dimanche 3 août 2003 Statut Membre Dernière intervention 29 mars 2010 - 28 mars 2010 à 23:32
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/42493-savoir-si-le-visiteur-est-un-robot-d-un-moteur-de-recherche

Clad49 Messages postés 265 Date d'inscription dimanche 3 août 2003 Statut Membre Dernière intervention 29 mars 2010
28 mars 2010 à 23:32
Les dernières ip crawltrack :

$IPtab[] = '204.236.235.245'; //Alexa

$IPtab[] = '66.235.112.'; //Ask Jeeves/Teoma
$IPtab[] = '66.235.124.';

$IPtab[] = '220.181.'; //Baiduspider
$IPtab[] = '61.135.168.';

$IPtab[] = '208.115.111.242'; //DotBot

$IPtab[] = '88.131.106.'; //Entireweb

$IPtab[] = '193.47.80.36'; //Exabot

$IPtab[] = '66.249.71.75'; //Google-Adsense

$IPtab[] = '212.117.183.169'; //GoogleBot

$IPtab[] = '207.46.'; //MSN Bot
$IPtab[] = '65.55.';

$IPtab[] = '66.219.58.42'; //Metadata Labs

$IPtab[] = '38.99.97.118'; //ScoutJet

$IPtab[] = '67.195.110.163'; //Slurp Inktomi (Yahoo)
$IPtab[] = '72.30.161.225';

$IPtab[] = '81.19.66.89'; //StackRambler

$IPtab[] = '67.218.116.162'; //Twiceler

$IPtab[] = '193.252.118.'; //VoilaBot
$IPtab[] = '69.41.173.145';
$IPtab[] = '81.52.143.';

$IPtab[] = '77.88.31.247'; //Yandex

$IPtab[] = '119.235.237.'; //Yeti
cs_Anto1982 Messages postés 4 Date d'inscription jeudi 17 janvier 2008 Statut Membre Dernière intervention 31 janvier 2009
10 oct. 2008 à 12:20
Ne peut-on pas imaginer un "piège" à robots. J'en ai codé un (le code est en ligne sur le site).
Le principe est de récupérer l'IP sur une page cachée (lien gif transparent dans le coin de la page)

=> Aucun humain ne visitera cette page (donc on a une liste des robots).

Ensuite, pour savoir si le robot est "clean" j'ai imaginé un piège en utilisant 2 pages dissimulées dont une seule est interdite dans le fichier robots.txt.

Dans le cas ou aucune de ces 2 pages n'est visitée et que le nombre de requetes provenant d'une meme IP dans un espace de temps donné est superieur x, j'estime qu'il s'agit d'un mauvais robot... (dans ce cas, je compte le nombre de requetes sur 5mn par exemple, si le nombre est superieur a 500, il ne s'agit pas d'un humain... si le robot ne visite pas la page dissimulée autorisée, il s'agit donc d'un mauvais robot)

Si le robot visite une page interdite par mon fichier robot, il s'agit également d'un mauvais robot....

Le seul probleme c'est que si un "mauvais" robot se comporte comme un "bon" robot (qu'il suit les directives du fichier robots.txt), je ne peux pas le détecter...
sy125gi Messages postés 5 Date d'inscription mardi 2 janvier 2007 Statut Membre Dernière intervention 3 juin 2009
10 juil. 2007 à 19:20
Et en fait, il faut metre ce fichier à quel endroit du site?
kiki67100 Messages postés 313 Date d'inscription samedi 6 mai 2006 Statut Membre Dernière intervention 10 août 2013 1
10 juil. 2007 à 15:50
Garde les ips c'est plus sûr que les user agent
Simpa la source ;)

(tu aurais pus mettre tout les ips dans un fichier aussi )

@++
MadM@tt Messages postés 2167 Date d'inscription mardi 11 novembre 2003 Statut Membre Dernière intervention 16 juillet 2009 1
29 juin 2007 à 15:12
Merci pour ta précision, c'est mis à jour.

Et merci pour ta liste d'IP
SrDjay Messages postés 1 Date d'inscription vendredi 29 juin 2007 Statut Membre Dernière intervention 29 juin 2007
29 juin 2007 à 10:34
Bon día,

Une petite chose:
remplace : strpos($IPtab[$t], $_SERVER['REMOTE_ADDR'])
par : strpos($_SERVER['REMOTE_ADDR'],$IPtab[$t])
(Voila pourquoi ca marche pas amery...)

Et pour tout ce qui souhaitent mettre à jour les IP:
http://www.crawltrack.fr/robot/index.php?navig=8&period=3&site=2

Bonne continuation MadM@tt,

Saludos,
cpp4ever Messages postés 2 Date d'inscription mercredi 29 novembre 2000 Statut Membre Dernière intervention 7 mai 2007
7 mai 2007 à 15:13
oups, effectivement
faut m'excuser, je croise tous le temps des coders
qui ne se donne jamais la peine d'aller voir le manuel de php,
que j'ai pris de mauvaises habitudes.
kankrelune Messages postés 1293 Date d'inscription mardi 9 novembre 2004 Statut Membre Dernière intervention 21 mai 2015
7 mai 2007 à 15:07
@ cpp4ever... oui merci ça fait un bail que je connais in_array()... lol... regarde bien la source avant de faire ce genre de réflection... tu remarquera que le tableau $ipTable contiens des plages d'ip et non pas que des ip complètes... et dans ce cas in_array() ne sert strictement à rien... à la limite preg_grep() aurait fait l'affaire mais perso je préfère la boucle... .. .

@ tchaOo°
cpp4ever Messages postés 2 Date d'inscription mercredi 29 novembre 2000 Statut Membre Dernière intervention 7 mai 2007
7 mai 2007 à 14:05
vous etes au courant que le module php a des centaines de fonctions prédéfinie.
par exemple in_array :

if (in_array ($_SERVER['REMOTE_ADDR'], $IPtab)) {
return TRUE;
}
else {
return FALSE;
}

quant aux ip des bots je crois qu'il faut faire le tour des moteurs de recherche.
cs_amery Messages postés 8 Date d'inscription mercredi 16 août 2006 Statut Membre Dernière intervention 28 juin 2007
2 mai 2007 à 16:30
J'ai essayé la fonction, mais ça n'a pas l'air de fonctionner. Par exemple, l'adresse Ip 66.249.66.133 n'est pas reconnu comme celle d'un moteur.

Amery
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
1 mai 2007 à 19:48
@kankrelune : Bon sang de bon soir... Merci... Je ne savais pas exactement étaient évaluées les conditions multiples par if... J'ai fait un test pour vérifier tes dires (c'est pas que j'ai pas confiance, mais là, au moins, je peux me permettre de l'affirmer à mon tour si besoin, puisque j'ai expérimenté).
Donc merci pour ces petits détails qui enrichissent tous les jours ma culture de geek...
MadM@tt Messages postés 2167 Date d'inscription mardi 11 novembre 2003 Statut Membre Dernière intervention 16 juillet 2009 1
1 mai 2007 à 14:09
"Je conseillerais plutôt de vérifier l'user_agent qui, lui, est toujours défini par les bots des moteurs de recherche."
>> Si c'est bien défini par tous les bots alors oui, mais j'avais lu que c'était pas toujours le cas...
kankrelune Messages postés 1293 Date d'inscription mardi 9 novembre 2004 Statut Membre Dernière intervention 21 mai 2015
1 mai 2007 à 12:08
@ neigedhiver... non car la première instruction de la condition étant fausse la seconde n'est pas vérifiée... .. .

@ Astalavista... pas forcement... foreach travail sur une copie du tableau, for non... après c'est une question de perf et de façon de faire... pour gagner en rapidité j'aurais tendance à faire...

$i = -1;
while(isset($IPtab[++$i]))
{
...
}

@ tchaOo°
Skreo Messages postés 53 Date d'inscription samedi 12 novembre 2005 Statut Membre Dernière intervention 25 août 2008
1 mai 2007 à 10:00
MadM@tt, ta méthode est lourde et pas très fiable (je ne pense pas que la liste des ips soit à jour).
Je conseillerais plutôt de vérifier l'user_agent qui, lui, est toujours défini par les bots des moteurs de recherche.
Voilà ce que je fais :

$isBot = preg_match('#googlebot|mediapartners|slurp|voilabot|msnbot|zyborg|fast-webcrawler|deepindex|teoma|directhit|walhello|gigabot|henrilerobotmirago|psbot|szukacz|openbot|dloader#i', $_SERVER['HTTP_USER_AGENT']);
MadM@tt Messages postés 2167 Date d'inscription mardi 11 novembre 2003 Statut Membre Dernière intervention 16 juillet 2009 1
30 avril 2007 à 20:08
@Kankrelune > Ok j'avais oublié la nuance < et <= merci
cs_Astalavista Messages postés 192 Date d'inscription lundi 24 décembre 2001 Statut Membre Dernière intervention 3 février 2010
30 avril 2007 à 19:04
kankrelune : Moi je me pose pas de question j'aurais pris un foreach et c'est bon ... il a été inventer pour le PHP autant l'utiliser ... non ?
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
30 avril 2007 à 17:10
Alors je vais encore chipoter (j'adooooore ça).

if(isset($_SERVER['REMOTE_ADDR']) && !empty($_SERVER['REMOTE_ADDR']))

Là aussi, syntaxiquement, tu vérifies si une variable potentiellement non instanciée est vide... Le fait de vérifier qu'elle existe ne la fait pas exister si tel n'est pas le cas...
Puor bien faire, il faudrait alors faire un autre test avec empty() dans le bloc if.
Non ?
kankrelune Messages postés 1293 Date d'inscription mardi 9 novembre 2004 Statut Membre Dernière intervention 21 mai 2015
30 avril 2007 à 16:49
@ neigedhiver... oui ça marche mais syntaxiquement parlant c'est incorrect car tu teste si une variable non instanciée est vide... .. .

@ MadM@tt... non... soit tu fais...

for($t=0,$max=count($IPtab)-1;$t<=$max;++$t)

soit tu fais

for($t=0,$max=count($IPtab);$t<$max;++$t)

la deuxième étant la plus simple... .. .

@ tchaOo°
MadM@tt Messages postés 2167 Date d'inscription mardi 11 novembre 2003 Statut Membre Dernière intervention 16 juillet 2009 1
30 avril 2007 à 16:44
Ok mais alors si mon tableau va de 0 à count() - 1, il faut donc une boucle :
for($t 0, $max count($IPtab) - 1; $t < $max; ++$t) ??
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
30 avril 2007 à 15:36
Je peux me permettre une remarque ?
empty($var) retourne true si :
- la variable $var est vide ( $var = '' )
- la variable $var n'est pas définie

Il me semble donc que le test isset($_SERVER['REMOTE_ADDR']) est inutile : si la variable $_SERVER['REMOTE_ADDR'] n'est pas vide, alors elle est définie.
kankrelune Messages postés 1293 Date d'inscription mardi 9 novembre 2004 Statut Membre Dernière intervention 21 mai 2015
30 avril 2007 à 15:34
pas exactement... en fait $i++ c'est de la post incrémentassion et ++$i de la pré incrementassion... .. .

Dans le premier cas l'instruction, si instruction il y a, est exécutée puis la variable est incrémentée de 1... dans le second cas la variable est incrémentée puis l'instruction est exécutée... exemple...

$a = 1;
$b = $a++;

echo '$a '.$a.',$b '.$b; // affichera $a = 2,$b = 1

---------------

$a = 1;
$b = ++$a;

echo '$a '.$a.',$b '.$b; // affichera $a = 2,$b = 2

Hormis cette petite différence la pré incrémentassion est légèrement plus rapide que la post incrémentassion car en pré inc php ne se pose pas de question et incrémente directement la variable alors qu'en post inc php garde en mémoire qu'il doit incrémenter la variable après avoir exécuté l'instruction en cours... .. . ;o)

@ tchaOo°
MadM@tt Messages postés 2167 Date d'inscription mardi 11 novembre 2003 Statut Membre Dernière intervention 16 juillet 2009 1
30 avril 2007 à 15:22
Ok c'est mis à jour, merci ;-), par contre j'en déduis que le $t++ et ++$t c'est la meme chose.
kankrelune Messages postés 1293 Date d'inscription mardi 9 novembre 2004 Statut Membre Dernière intervention 21 mai 2015
30 avril 2007 à 15:13
Pareil que neigedhiver... .. . ;o)

Pour finir plutot que de faire...

$IP = $_SERVER['REMOTE_ADDR']
$max = count($IPtab) - 1;
for($t = 0; $t <= $max; $t++) {
if (strpos($IPtab[$t], $IP) === 0)
{
return true;
}
}
return false;

autant faire

if(isset($_SERVER['REMOTE_ADDR']) && !empty($_SERVER['REMOTE_ADDR']))
{
for($t=0,$max=count($IPtab);$t<$max;++$t)
{
if (strpos($IPtab[$t], $_SERVER['REMOTE_ADDR']) === 0)
return true;
}
}
return false;

;o)

@ tchaOo°
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
30 avril 2007 à 15:12
Je me rends compte que j'ai pas écrit du tout ce que je voulais dire... Je suis fatigué, j'ai plus l'habitude de bosser.
Euh donc je voulais dire que c'est sympa quand les gens prennent bien les commentaires et s'en servent de manière constructive, sans se vexer, etc.
Mais je crois que tu avais compris...
Bonne continuation.
MadM@tt Messages postés 2167 Date d'inscription mardi 11 novembre 2003 Statut Membre Dernière intervention 16 juillet 2009 1
30 avril 2007 à 14:58
oui je te comprend, je suis assez actif sur vbfrance je vois de quoi tu parle ^^
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
30 avril 2007 à 14:40
Je sais pas si tu imagines à quel point c'est sympa de faire des commentaires qui ne sont pas mal pris et qui servent à quelque chose...
MadM@tt Messages postés 2167 Date d'inscription mardi 11 novembre 2003 Statut Membre Dernière intervention 16 juillet 2009 1
30 avril 2007 à 14:24
Voilà mis à jour ^^

C'est sympa d'avoir du monde pour repasser sur son code ;) merci beaucoup
kankrelune Messages postés 1293 Date d'inscription mardi 9 novembre 2004 Statut Membre Dernière intervention 21 mai 2015
30 avril 2007 à 13:58
Ah au fait... vire moi ce sale $REMOTE_ADDR et remplace le par $_SERVER['REMOTE_ADDR']... .. . ;o)

@ tchaOo°
kankrelune Messages postés 1293 Date d'inscription mardi 9 novembre 2004 Statut Membre Dernière intervention 21 mai 2015
30 avril 2007 à 13:57
for($t=1,$nb=count($IPtab);$t<=$nb;++$t)

Histoire d'optimiser encore un peu... perso je ne suis pas fan de cette méthode car si le bot à changé d'adresse ip ou s'il n'est pas répertorié ton script ne sert à rien... le mieux serait de faire un lien caché vers une page ou de compter le temps entre chaque ouverture de page et de stocker l'ip s'il sagit d'un bot... .. .

@ tchaOo°
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
30 avril 2007 à 06:44
Salut,

En fait, le mieux, pour la déclaration du tableau, c'est encore array() :

$IPtab = array(
'66.249.', // Googlebot
'207.68.146.', // MSN Bot
'65.54.188.', // MSN Bot
etc
);

Je trouve que c'est encore plus propre et plus joli.
cs_Astalavista Messages postés 192 Date d'inscription lundi 24 décembre 2001 Statut Membre Dernière intervention 3 février 2010
30 avril 2007 à 01:37
Je voit que j'ai aidé :), je te remercie neigedhiver d'avoir affirmer ce que j'ai marqué ...

Ha oui, il y a encore une petite erreur :
for($t = 1; $t <= $max; $t = $t++)
S'utilise plutôt comme ca :
for($t = 1; $t <= $max; $t++)

ton count doit s'écrire en minuscule

à mon avis, le foreach est un peut plus adapté.
Si un jour tu supprime la clef 19 (par exemple), il faudra changer toutes tes autres clef.
Mais bon, si tu insiste pour utiliser ton for, ajoute tes IP de cette façon :
$IPtab[] = '66.249.';
$IPtab[] = '207.68.146.';
L'ajout se fera à la suite, et 0 par défaut.
MadM@tt Messages postés 2167 Date d'inscription mardi 11 novembre 2003 Statut Membre Dernière intervention 16 juillet 2009 1
29 avril 2007 à 21:02
Ahhhh bien sur !

Merci pour le tuyeau ;-)
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
29 avril 2007 à 20:44
Re,

Non non, strpos() est une très bonne solution, si on ne se contente pas de vérifier que la chaine a été trouvée, mais si on vérifie aussi la position (valeur retournée par strpos() justement !). En plus, c'est plus court :

if (strpos($IPtab[$t], $IP) === 0)
{
return true;
}

Return va automatiquement sortir de la fonction et retourner true quand la chaine est trouvée.
MadM@tt Messages postés 2167 Date d'inscription mardi 11 novembre 2003 Statut Membre Dernière intervention 16 juillet 2009 1
29 avril 2007 à 18:24
Voilà c'est mis à jour.

Par contre je me pose la question concernant la recherche de l'ip dans l'ip du visiteur :
// Récupère la partie gauche de la chaine
$left = substr($IP, 0, strlen($IPtab[$t]));
if ($left == $IPtab[$t]) {
$Return = true;
break;
}

Je trouve ça bete de faire un substr à chaque boucle, mais comment faire une comparaison de chaine en partant à gauche de la chaine ?
(car les adresses IP du tableau sont de la form 168.69. mais avec un strpos il peut me le trouver dans une adresse de la forme 145.168.69....)
MadM@tt Messages postés 2167 Date d'inscription mardi 11 novembre 2003 Statut Membre Dernière intervention 16 juillet 2009 1
29 avril 2007 à 18:18
Ok merci beaucoup pour les infos, php a tellement de fonctions pour faire la meme chose qu'il est difficile de savoir laquelle utiliser.

Je vais m'empresser de modifier ça, surtout que j'utilise cette méthode dans toutes mes boucles for de mon site ^^
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
29 avril 2007 à 17:55
Salut,

Je ne crois pas que foreach() soit tellement plus rapide que for().
Par contre, la syntaxe de ta boucle est à proscrire à tout prix, parce que tu utilises la fonction count à chaque itération, ce qui est très couteux en performances.

Dans ton cas, foreach() est plus adapté car sa syntaxe est plus claire et tout aussi efficace.

Pour garder for() il faudrait faire comme ceci :
$nb = count($IPtab);
for($t = 1; $t <= $nb; $t++) {

La syntaxe $t++ est équivalente à $t = $t +1, mais plus courte, tout aussi claire et plus performante puisqu'elle ne fait appel qu'une seule fois à la variable (qui est lue chaque fois dans la pile, ne pas l'oublier) et qu'elle est optimisée pour cette opération...
MadM@tt Messages postés 2167 Date d'inscription mardi 11 novembre 2003 Statut Membre Dernière intervention 16 juillet 2009 1
29 avril 2007 à 13:35
Merci pour le commentaire, par contre j'aurais besoin d'un peu d'explication :
pourquoi privilegier foreach plutot que for ? c'est plus rapide ?

Et de ton code j'en déduis que l'instruction "return" fait terminer la fonction ? (ce qui effectivement est bien mieux que ce que j'ai fait)

Pour le fichier, bonne idée, mais si ce code est appelé à chaque page vue ça risque de faire perdre beaucoup de temps s'il faut que j'ouvre le fichier à chaque fois, et que je parse le contenu.

Merci
cs_Astalavista Messages postés 192 Date d'inscription lundi 24 décembre 2001 Statut Membre Dernière intervention 3 février 2010
29 avril 2007 à 02:48
Pas mal, mais :
Utilise plutot un fichier pour ta liste d'adresses, et pour vérifier utilse plûtot ceci :
$IP = $REMOTE_ADDR;
// Vérifie chaque adresse
foreach( $IPtab as $IP_Rechercher)
if((strrpos($IP, $IP_Rechercher) === 0)return FALSE;
return TRUE;
Rejoignez-nous