Detección de rastreadores web honestos


Me gustaría detectar (en el lado del servidor) qué solicitudes son de bots. No me importan los bots maliciosos en este momento, solo los que están jugando bien. He visto algunos enfoques que en su mayoría implican hacer coincidir la cadena del agente de usuario con palabras clave como'bot'. Pero eso parece incómodo, incompleto e inalcanzable. Entonces, ¿alguien tiene más enfoques sólidos? Si no, ¿tiene algún recurso que utilice para mantenerse al día con todos los agentes de usuario amigables?

Si tienes curiosidad: No estoy tratando de hacer nada en contra de ninguna política de motores de búsqueda. Tenemos una sección del sitio donde un usuario se presenta al azar con una de varias versiones ligeramente diferentes de una página. Sin embargo, si se detecta un rastreador web, siempre les daremos la misma versión para que el índice sea consistente.

También estoy usando Java, pero me imagino que el enfoque sería similar para cualquier tecnología del lado del servidor.

Author: j0k, 2009-02-13

6 answers

Puede encontrar una base de datos muy completa de datos sobre rastreadores web conocidos "buenos" en el robotstxt.org Base de datos de robots . Utilizar estos datos sería mucho más efectivo que simplemente hacer coincidir bot en el agente de usuario.

 24
Author: Sparr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-13 02:12:00

Dijiste que hacer coincidir el agente de usuario en 'bot' puede ser incómodo, pero hemos encontrado que es una buena coincidencia. Nuestros estudios han demostrado que cubrirá aproximadamente el 98% de las visitas que reciba. Tampoco hemos encontrado ninguna coincidencia de falsos positivos todavía. Si quieres aumentar esto hasta un 99.9%, puedes incluir algunas otras coincidencias conocidas como 'crawler', 'baiduspider', 'ia_archiver', 'curl', etc. Hemos probado esto en nuestros sistemas de producción durante millones de visitas.

Aquí hay algunos c# soluciones para usted:

1) Más simple

Es el más rápido cuando se procesa un fallo. es decir, el tráfico de un no-bot-un usuario normal. Captura el 99% de los rastreadores.

bool iscrawler = Regex.IsMatch(Request.UserAgent, @"bot|crawler|baiduspider|80legs|ia_archiver|voyager|curl|wget|yahoo! slurp|mediapartners-google", RegexOptions.IgnoreCase);

2) Medio

Es el más rápido cuando se procesa un golpe. es decir, el tráfico de un bot. Bastante rápido para fallar también. Captura cerca del 100% de los rastreadores. Coincide con 'bot', 'crawler', 'spider' por adelantado. Puede agregar a él cualquier otro rastreador conocido.

List<string> Crawlers3 = new List<string>()
{
    "bot","crawler","spider","80legs","baidu","yahoo! slurp","ia_archiver","mediapartners-google",
    "lwp-trivial","nederland.zoek","ahoy","anthill","appie","arale","araneo","ariadne",            
    "atn_worldwide","atomz","bjaaland","ukonline","calif","combine","cosmos","cusco",
    "cyberspyder","digger","grabber","downloadexpress","ecollector","ebiness","esculapio",
    "esther","felix ide","hamahakki","kit-fireball","fouineur","freecrawl","desertrealm",
    "gcreep","golem","griffon","gromit","gulliver","gulper","whowhere","havindex","hotwired",
    "htdig","ingrid","informant","inspectorwww","iron33","teoma","ask jeeves","jeeves",
    "image.kapsi.net","kdd-explorer","label-grabber","larbin","linkidator","linkwalker",
    "lockon","marvin","mattie","mediafox","merzscope","nec-meshexplorer","udmsearch","moget",
    "motor","muncher","muninn","muscatferret","mwdsearch","sharp-info-agent","webmechanic",
    "netscoop","newscan-online","objectssearch","orbsearch","packrat","pageboy","parasite",
    "patric","pegasus","phpdig","piltdownman","pimptrain","plumtreewebaccessor","getterrobo-plus",
    "raven","roadrunner","robbie","robocrawl","robofox","webbandit","scooter","search-au",
    "searchprocess","senrigan","shagseeker","site valet","skymob","slurp","snooper","speedy",
    "curl_image_client","suke","www.sygol.com","tach_bw","templeton","titin","topiclink","udmsearch",
    "urlck","valkyrie libwww-perl","verticrawl","victoria","webscout","voyager","crawlpaper",
    "webcatcher","t-h-u-n-d-e-r-s-t-o-n-e","webmoose","pagesinventory","webquest","webreaper",
    "webwalker","winona","occam","robi","fdse","jobo","rhcs","gazz","dwcp","yeti","fido","wlm",
    "wolp","wwwc","xget","legs","curl","webs","wget","sift","cmc"
};
string ua = Request.UserAgent.ToLower();
bool iscrawler = Crawlers3.Exists(x => ua.Contains(x));

3) Paranoico

Es bastante rápido, pero un poco más lento que las opciones 1 y 2. Es el más preciso, y le permite mantener las listas si lo desea. Puede mantener una lista separada de nombres con 'bot' en ellos si tiene miedo de falsos positivos en el futuro. Si tenemos una coincidencia corta, la registramos y comprobamos si hay un falso positivo.

// crawlers that have 'bot' in their useragent
List<string> Crawlers1 = new List<string>()
{
    "googlebot","bingbot","yandexbot","ahrefsbot","msnbot","linkedinbot","exabot","compspybot",
    "yesupbot","paperlibot","tweetmemebot","semrushbot","gigabot","voilabot","adsbot-google",
    "botlink","alkalinebot","araybot","undrip bot","borg-bot","boxseabot","yodaobot","admedia bot",
    "ezooms.bot","confuzzledbot","coolbot","internet cruiser robot","yolinkbot","diibot","musobot",
    "dragonbot","elfinbot","wikiobot","twitterbot","contextad bot","hambot","iajabot","news bot",
    "irobot","socialradarbot","ko_yappo_robot","skimbot","psbot","rixbot","seznambot","careerbot",
    "simbot","solbot","mail.ru_bot","spiderbot","blekkobot","bitlybot","techbot","void-bot",
    "vwbot_k","diffbot","friendfeedbot","archive.org_bot","woriobot","crystalsemanticsbot","wepbot",
    "spbot","tweetedtimes bot","mj12bot","who.is bot","psbot","robot","jbot","bbot","bot"
};

// crawlers that don't have 'bot' in their useragent
List<string> Crawlers2 = new List<string>()
{
    "baiduspider","80legs","baidu","yahoo! slurp","ia_archiver","mediapartners-google","lwp-trivial",
    "nederland.zoek","ahoy","anthill","appie","arale","araneo","ariadne","atn_worldwide","atomz",
    "bjaaland","ukonline","bspider","calif","christcrawler","combine","cosmos","cusco","cyberspyder",
    "cydralspider","digger","grabber","downloadexpress","ecollector","ebiness","esculapio","esther",
    "fastcrawler","felix ide","hamahakki","kit-fireball","fouineur","freecrawl","desertrealm",
    "gammaspider","gcreep","golem","griffon","gromit","gulliver","gulper","whowhere","portalbspider",
    "havindex","hotwired","htdig","ingrid","informant","infospiders","inspectorwww","iron33",
    "jcrawler","teoma","ask jeeves","jeeves","image.kapsi.net","kdd-explorer","label-grabber",
    "larbin","linkidator","linkwalker","lockon","logo_gif_crawler","marvin","mattie","mediafox",
    "merzscope","nec-meshexplorer","mindcrawler","udmsearch","moget","motor","muncher","muninn",
    "muscatferret","mwdsearch","sharp-info-agent","webmechanic","netscoop","newscan-online",
    "objectssearch","orbsearch","packrat","pageboy","parasite","patric","pegasus","perlcrawler",
    "phpdig","piltdownman","pimptrain","pjspider","plumtreewebaccessor","getterrobo-plus","raven",
    "roadrunner","robbie","robocrawl","robofox","webbandit","scooter","search-au","searchprocess",
    "senrigan","shagseeker","site valet","skymob","slcrawler","slurp","snooper","speedy",
    "spider_monkey","spiderline","curl_image_client","suke","www.sygol.com","tach_bw","templeton",
    "titin","topiclink","udmsearch","urlck","valkyrie libwww-perl","verticrawl","victoria",
    "webscout","voyager","crawlpaper","wapspider","webcatcher","t-h-u-n-d-e-r-s-t-o-n-e",
    "webmoose","pagesinventory","webquest","webreaper","webspider","webwalker","winona","occam",
    "robi","fdse","jobo","rhcs","gazz","dwcp","yeti","crawler","fido","wlm","wolp","wwwc","xget",
    "legs","curl","webs","wget","sift","cmc"
};

string ua = Request.UserAgent.ToLower();
string match = null;

if (ua.Contains("bot")) match = Crawlers1.FirstOrDefault(x => ua.Contains(x));
else match = Crawlers2.FirstOrDefault(x => ua.Contains(x));

if (match != null && match.Length < 5) Log("Possible new crawler found: ", ua);

bool iscrawler = match != null;

Notas:

  • Es tentador simplemente seguir agregando nombres a la expresión regular opción 1. Pero si haces esto se volverá más lento. Si desea una lista más completa, linq con lambda es más rápido.
  • Asegúrese .ToLower () está fuera de tu método linq – recuerda que el método es un bucle y que estarías modificando la cadena durante cada iteración.
  • Siempre ponga los bots más pesados al principio de la lista, para que coincidan antes.
  • Coloque las listas en una clase estática para que no se reconstruyan en cada vista de página.

Honeypots

La única alternativa real a esto es crear un enlace 'honeypot' en su sitio que solo un bot llegar. A continuación, registre las cadenas del agente de usuario que llegan a la página honeypot en una base de datos. Luego puede usar esas cadenas registradas para clasificar a los rastreadores.

Postives: Coincidirá con algunos rastreadores desconocidos que no se declaran a sí mismos.

Negatives: No todos los rastreadores cavan lo suficientemente profundo como para golpear cada enlace en su sitio, y por lo que no pueden llegar a su honeypot.

 80
Author: Dave Sumter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-26 10:55:53

Una sugerencia es crear un ancla vacía en su página que solo un bot seguiría. Los usuarios normales no verían el enlace, dejando arañas y bots a seguir. Por ejemplo, una etiqueta de anclaje vacía que apunte a una subcarpeta registraría una solicitud get en sus registros...

<a href="dontfollowme.aspx"></a>

Muchas personas usan este método mientras ejecutan un HoneyPot para atrapar bots maliciosos que no están siguiendo a los robots.archivo txt. Utilizo el método de anclaje vacío en un ASP.NET solución honeypot Le escribí a trap y bloquear a esos rastreadores espeluznantes...

 9
Author: Dscoduc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-13 02:18:43

Cualquier visitante cuya página de entrada sea /robots.txt es probablemente un bot.

 5
Author: Sparr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-13 02:06:57

Algo rápido y sucio como este podría ser un buen comienzo:

return if request.user_agent =~ /googlebot|msnbot|baidu|curl|wget|Mediapartners-Google|slurp|ia_archiver|Gigabot|libwww-perl|lwp-trivial/i

Nota: código rails, pero regex es generalmente aplicable.

 4
Author: Brian Armstrong,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-25 22:43:04

Estoy bastante seguro de que una gran proporción de bots no usan robots.txt, sin embargo, ese fue mi primer pensamiento.

Me parece que la mejor manera de detectar un bot es con el tiempo entre solicitudes, si el tiempo entre solicitudes es consistentemente rápido, entonces es un bot.

 0
Author: Stewart McKee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-21 07:57:13