如何用PHP识别机器人?

18
我正在为我的用户建立统计数据,并且不希望来自机器人的访问被计算在内。现在我有一个基本的php和mysql,每次调用页面时增加1。但是机器人也会被计入统计。有人能想到解决方法吗?主要是一些主流搜索引擎(如Google、Yahoo、Msn等)搞砸了事情。
7个回答

24

您可以检查用户代理字符串,其中包含空字符串或包含“robot”,“spider”,“crawler”,“curl”的字符串很可能是机器人。

preg_match('/robot|spider|crawler|curl|^$/i', $_SERVER['HTTP_USER_AGENT']));


6
非常有用。如果您将“机器人”替换为“bot”,则会更加有用,以匹配最活跃的机器人之一:“Mozilla / 5.0(兼容; Googlebot / 2.1; +http://www.google.com/bot.html)”。 - Simo A.
我建议明确匹配“googlebot”,因为匹配“bot”可能会排除潜在的良性用户代理。 - yagooar
2
我在 http://www.useragentstring.com/pages/Browserlist/ 上搜索了“bot”,但没有结果,所以我猜匹配“bot”不应该会产生误报。 - tomwoods
Yahoo Slurp!是另一个需要注意的网络爬虫... Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp) - Steven de Salas
这似乎是您的preg_match的改进版本:https://dev59.com/VnRB5IYBdhLWcg3wQVSV#15047834 - lucaferrario
@SimoA。您关于Googlebot的评论很好,可以融入到答案中。我没有看到这个评论,开始使用了这个正则表达式,显然错过了您提到的“Googlebot”。 - Bryan

10

您应该通过用户代理字符串进行过滤。您可以在此处找到大约300个常见机器人的用户代理列表:http://www.robotstxt.org/db.html 在运行SQL语句之前浏览该列表并忽略机器人用户代理应该解决您所有实际问题。

如果您不希望搜索引擎甚至进入页面,请使用基本的robots.txt文件来阻止它们。


6
我们有一个类似于您的用例,最近我们发现非常有帮助的选项是来自user-agent-string.infoUASParser class
这是一个PHP类,它会拉取最新的用户代理字符串定义并将其缓存在本地。该类可配置为根据需要频繁或不频繁地拉取这些定义。自动获取这些定义意味着您无需跟踪各种机器人用户代理的变化或新上市的机器人用户代理,尽管您正在依赖UAS.info准确执行此操作。
当调用该类时,它会解析当前访问者的用户代理并返回一个关联数组,以分解组成部分,例如:
Array
(
    [typ] => browser
    [ua_family] => Firefox
    [ua_name] => Firefox 3.0.8
    [ua_url] => http://www.mozilla.org/products/firefox/
    [ua_company] => Mozilla Foundation
    ........
    [os_company] => Microsoft Corporation.
    [os_company_url] => http://www.microsoft.com/
    [os_icon] => windowsxp.png
)

当UA被识别为可能属于人类访客时,字段typ将设置为browser,此时您可以更新统计信息。

这里有几个注意事项:

  • 您要依赖UAS.info提供的用户代理字符串准确且最新
  • 像Google和Yahoo这样的机器人会在其用户代理字符串中声明自己,但是这种方法仍将计算伪装成人类访客(发送欺骗性UA)的机器人的访问次数
  • @amdfan上面提到的,通过robots.txt阻止机器人应该可以阻止大部分机器人访问您的页面。如果您需要索引内容但不增加统计数据,则robots.txt方法不是一个现实选项

2
在增加页面浏览次数之前,请检查用户代理,但请记住这可能会被欺骗。 PHP通过$_SERVER['HTTP_USER_AGENT']公开用户代理,假设Web服务器提供此信息。有关$_SERVER的更多信息可以在http://www.php.net/manual/en/reserved.variables.server.php找到。
您可以在http://www.user-agents.org找到用户代理列表;谷歌搜索也会提供属于主要提供商的名称。第三个可能的来源是您的Web服务器访问日志(如果您可以聚合它们)。

2

100%工作的机器人检测器。它正在我的网站上工作,用于检测机器人、爬虫、蜘蛛和复制者。

function isBotDetected() {

    if ( preg_match('/abacho|accona|AddThis|AdsBot|ahoy|AhrefsBot|AISearchBot|alexa|altavista|anthill|appie|applebot|arale|araneo|AraybOt|ariadne|arks|aspseek|ATN_Worldwide|Atomz|baiduspider|baidu|bbot|bingbot|bing|Bjaaland|BlackWidow|BotLink|bot|boxseabot|bspider|calif|CCBot|ChinaClaw|christcrawler|CMC\/0\.01|combine|confuzzledbot|contaxe|CoolBot|cosmos|crawler|crawlpaper|crawl|curl|cusco|cyberspyder|cydralspider|dataprovider|digger|DIIbot|DotBot|downloadexpress|DragonBot|DuckDuckBot|dwcp|EasouSpider|ebiness|ecollector|elfinbot|esculapio|ESI|esther|eStyle|Ezooms|facebookexternalhit|facebook|facebot|fastcrawler|FatBot|FDSE|FELIX IDE|fetch|fido|find|Firefly|fouineur|Freecrawl|froogle|gammaSpider|gazz|gcreep|geona|Getterrobo-Plus|get|girafabot|golem|googlebot|\-google|grabber|GrabNet|griffon|Gromit|gulliver|gulper|hambot|havIndex|hotwired|htdig|HTTrack|ia_archiver|iajabot|IDBot|Informant|InfoSeek|InfoSpiders|INGRID\/0\.1|inktomi|inspectorwww|Internet Cruiser Robot|irobot|Iron33|JBot|jcrawler|Jeeves|jobo|KDD\-Explorer|KIT\-Fireball|ko_yappo_robot|label\-grabber|larbin|legs|libwww-perl|linkedin|Linkidator|linkwalker|Lockon|logo_gif_crawler|Lycos|m2e|majesticsEO|marvin|mattie|mediafox|mediapartners|MerzScope|MindCrawler|MJ12bot|mod_pagespeed|moget|Motor|msnbot|muncher|muninn|MuscatFerret|MwdSearch|NationalDirectory|naverbot|NEC\-MeshExplorer|NetcraftSurveyAgent|NetScoop|NetSeer|newscan\-online|nil|none|Nutch|ObjectsSearch|Occam|openstat.ru\/Bot|packrat|pageboy|ParaSite|patric|pegasus|perlcrawler|phpdig|piltdownman|Pimptrain|pingdom|pinterest|pjspider|PlumtreeWebAccessor|PortalBSpider|psbot|rambler|Raven|RHCS|RixBot|roadrunner|Robbie|robi|RoboCrawl|robofox|Scooter|Scrubby|Search\-AU|searchprocess|search|SemrushBot|Senrigan|seznambot|Shagseeker|sharp\-info\-agent|sift|SimBot|Site Valet|SiteSucker|skymob|SLCrawler\/2\.0|slurp|snooper|solbot|speedy|spider_monkey|SpiderBot\/1\.0|spiderline|spider|suke|tach_bw|TechBOT|TechnoratiSnoop|templeton|teoma|titin|topiclink|twitterbot|twitter|UdmSearch|Ukonline|UnwindFetchor|URL_Spider_SQL|urlck|urlresolver|Valkyrie libwww\-perl|verticrawl|Victoria|void\-bot|Voyager|VWbot_K|wapspider|WebBandit\/1\.0|webcatcher|WebCopier|WebFindBot|WebLeacher|WebMechanic|WebMoose|webquest|webreaper|webspider|webs|WebWalker|WebZip|wget|whowhere|winona|wlm|WOLP|woriobot|WWWC|XGET|xing|yahoo|YandexBot|YandexMobileBot|yandex|yeti|Zeus/i', $_SERVER['HTTP_USER_AGENT'])
    ) {
        return true; // 'Above given bots detected'
    }

    return false;

} // End :: isBotDetected()

1
像魔术一样好用! - Uchenna Ajah

0
你尝试过通过它们的用户代理信息来识别它们吗?简单的谷歌搜索应该会给出Google等公司使用的用户代理。
当然,这并不是万无一失的,但大多数主要公司的爬虫都提供了明显的用户代理。
编辑:假设您不想限制机器人访问,而只是不计算其访问次数在您的统计数据中。

0

这个函数对我很有用,我在https://www.cult-f.net/detect-crawlers-with-php/网站上找到了它:

<?php
  $crawlers = array(
    'Google'=>'Google',
    'MSN' => 'msnbot',
    'Rambler'=>'Rambler',
    'Yahoo'=> 'Yahoo',
    'AbachoBOT'=> 'AbachoBOT',
    'accoona'=> 'Accoona',
    'AcoiRobot'=> 'AcoiRobot',
    'ASPSeek'=> 'ASPSeek',
    'CrocCrawler'=> 'CrocCrawler',
    'Dumbot'=> 'Dumbot',
    'FAST-WebCrawler'=> 'FAST-WebCrawler',
    'GeonaBot'=> 'GeonaBot',
    'Gigabot'=> 'Gigabot',
    'Lycos spider'=> 'Lycos',
    'MSRBOT'=> 'MSRBOT',
    'Altavista robot'=> 'Scooter',
    'AltaVista robot'=> 'Altavista',
    'ID-Search Bot'=> 'IDBot',
    'eStyle Bot'=> 'eStyle',
    'Scrubby robot'=> 'Scrubby',
    );
 
function crawlerDetect($USER_AGENT)
{
    // to get crawlers string used in function uncomment it
    // it is better to save it in string than use implode every time
    // global $crawlers
    // $crawlers_agents = implode('|',$crawlers);
    $crawlers_agents = 'Google|msnbot|Rambler|Yahoo|AbachoBOT|accoona|AcioRobot|ASPSeek|CocoCrawler|Dumbot|FAST-WebCrawler|GeonaBot|Gigabot|Lycos|MSRBOT|Scooter|AltaVista|IDBot|eStyle|Scrubby';
 
    if ( strpos($crawlers_agents , $USER_AGENT) === false )
       return false;
    // crawler detected
    // you can use it to return its name
    /*
    else {
       return array_search($USER_AGENT, $crawlers);
    }
    */
}
 
// example
 
$crawler = crawlerDetect($_SERVER['HTTP_USER_AGENT']);
 
if ($crawler )
{
   // it is crawler, it's name in $crawler variable
}
else
{
   // usual visitor
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接