如何识别网络爬虫?

36

如何过滤掉网络爬虫等非人类访问记录?

我使用maxmind.com从IP地址请求城市信息。如果我必须为包括网络爬虫、机器人等在内的所有访问记录付费,这样并不便宜。


为什么不对数据库进行许可,这样您就可以在本地使用它,而无需进行每个请求的付款呢?! - ThiefMaster
缓存来自maxmind.com的结果怎么样?以这种方式,我认为由机器人/人类引起的查询比率将是可以接受的。 - Saic Siquot
我意识到这是一个相当古老的帖子。我也在使用此服务,并发现使用AJAX是过滤所有机器人的一种可靠方法。我们最初只使用PHP启动了此功能,几天内就几乎用完了本月的分配量。切换到AJAX后,它变得更加可靠。个人而言,我会使用新的HTML 5 GEO位置,因为它更准确,但所有者不喜欢浏览器的确认提示。 - Michael E
我认为你无法限制爬虫而不影响真实用户。祝你好运。 - Alex MAN
6个回答

60

有两种通用方法来检测机器人,我称之为“礼貌/被动”和“侵略性”。基本上,你必须给你的网站一个心理障碍。

礼貌/被动

这些是告诉网络爬虫他们不应该爬取你的网站并限制你被爬取频率的礼貌方式。通过robots.txt文件确保礼貌,其中你指定哪些机器人,如果有的话,可以爬取你的网站以及你的网站可以被爬取的频率。这假设你所处理的机器人是礼貌的。

侵略性

让机器人远离你的网站的另一种方式是变得侵略。

User Agent (用户代理)

一些侵略行为包括(如其他用户之前提到的)过滤用户代理字符串。这可能是最简单但也是最不可靠的检测是否是用户的方法。许多机器人倾向于欺骗用户代理,有些出于合法原因(即他们只想爬取移动内容),而其他人则不想被识别为机器人。更糟糕的是,一些机器人伪造合法/礼貌的机器人代理,如google、microsoft、lycos等爬虫的用户代理,这些通常被认为是礼貌的。依靠用户代理可能有所帮助,但不能单独依靠它。

还有更侵略的方法来处理伪造用户代理且不遵守你的robots.txt文件的机器人:

Bot Trap (机器人陷阱)

我喜欢把它想象成“捕蝇草”,它基本上惩罚任何想和你玩花招的机器人。

一个机器人陷阱可能是找到不遵守你的robots.txt文件的机器人最有效的方法,而不会影响你的网站可用性。创建机器人陷阱可以确保只捕获机器人而不是真实用户。基本的方法是设置一个目录,在你的robots.txt文件中标记为禁止访问,这样任何有礼貌的机器人都不会掉进陷阱。第二件事情是在你的网站上放置一个“隐藏”的链接指向机器人陷阱目录(这样确保真实用户永远不会去那里,因为真实用户永远不会点击看不见的链接)。最后,禁止任何访问机器人陷阱目录的IP地址。
以下是如何实现这一点的说明: 创建一个机器人陷阱(或者使用PHP机器人陷阱)。
注意:当然,一些机器人足够聪明,能够读取你的robots.txt文件,看到你标记为“禁止访问”的所有目录,并且仍然忽略你的礼貌设置(例如爬行速率和允许的机器人)。这些机器人可能不会掉进你的机器人陷阱,尽管它们不礼貌。 激进 我认为这对于一般观众(和一般使用)来说实际上太过激进了,因此如果18岁以下的孩子,请将他们带到另一个房间!你可以通过简单地不指定robots.txt文件使机器人陷阱“激进”。在这种情况下,任何爬行隐藏链接的任何机器人都可能最终掉进机器人陷阱,你可以禁止所有机器人的访问!
不建议这样做的原因是你可能确实希望某些机器人爬行你的网站(例如用于网站索引的Google、Microsoft或其他机器人)。允许来自Google、Microsoft、Lycos等机器人的友好爬行将确保你的站点被索引并在人们在其喜爱的搜索引擎上搜索时出现。 自毁另一种限制机器人在您网站上爬行的方法是提供 CAPTCHA 或其他挑战,这些挑战机器人无法解决。这会给您的用户带来不便,我认为任何使您的网站难以使用(例如 CAPTCHA)的东西都是"自毁"的。当然,这实际上不会阻止机器人重复尝试爬行您的网站,它只会让机器人对您的网站失去兴趣。有办法"绕过" CAPTCHA,但很难实现,所以我不会深入探讨这个问题。
结论
针对您的目的,可能处理机器人的最佳方式是采用上述策略的组合:
1. 过滤用户代理。 2. 设置一个机器人陷阱(暴力陷阱)。
捕获所有进入暴力机器人陷阱的机器人,然后简单地将其 IP 地址列入黑名单(但不要阻止它们)。这样你仍然可以获得被机器人爬取的"好处",但你不必支付检查由于进入你的机器人陷阱而被列入黑名单的 IP 地址的费用。

注意:据我所知,reCAPTCHA是谷歌拥有的,因此...理论上他们可以轻松地绕过它。 - Francisco Presencia
创意!仍然非常有效! - GTodorov
我认为维纳斯陷阱被称为“蜜罐”。 - Sebastian Mach

9
您可以检查USER_AGENT,例如:
function crawlerDetect($USER_AGENT)
{
    $crawlers = array(
    array('Google', 'Google'),
    array('msnbot', 'MSN'),
    array('Rambler', 'Rambler'),
    array('Yahoo', 'Yahoo'),
    array('AbachoBOT', 'AbachoBOT'),
    array('accoona', 'Accoona'),
    array('AcoiRobot', 'AcoiRobot'),
    array('ASPSeek', 'ASPSeek'),
    array('CrocCrawler', 'CrocCrawler'),
    array('Dumbot', 'Dumbot'),
    array('FAST-WebCrawler', 'FAST-WebCrawler'),
    array('GeonaBot', 'GeonaBot'),
    array('Gigabot', 'Gigabot'),
    array('Lycos', 'Lycos spider'),
    array('MSRBOT', 'MSRBOT'),
    array('Scooter', 'Altavista robot'),
    array('AltaVista', 'Altavista robot'),
    array('IDBot', 'ID-Search Bot'),
    array('eStyle', 'eStyle Bot'),
    array('Scrubby', 'Scrubby robot')
    );

    foreach ($crawlers as $c)
    {
        if (stristr($USER_AGENT, $c[0]))
        {
            return($c[1]);
        }
    }

    return false;
}

// example

$crawler = crawlerDetect($_SERVER['HTTP_USER_AGENT']);

8
用户代理($_SERVER['HTTP_USER_AGENT'])通常可以识别连接代理是浏览器还是机器人。查看访问您的站点的爬虫的用户代理的日志/分析。相应地进行过滤。
请注意,用户代理是由客户端应用程序提供的标头。因此,它可以是几乎任何东西,并且不应被100%信任。请做好计划。

1
这是一个很好的回答,但你应该添加免责声明,即用户代理检查仅适用于能够识别自己的网络爬虫。欺骗用户代理字符串是微不足道的。 - jedwards
@jadewards,我赞同这一点...很多网络爬虫伪造用户代理。有时候这是必要的,因为网站根据用户代理提供不同的内容(例如,移动浏览器与标准浏览器)。 - Kiril
你应该添加一个指向最新网站的链接,因为这是你好回答的主要原因。 - rubo77

5
检查User-Agent可以保护您免受Google和Yahoo等合法机器人的影响。
但是,如果您还遭受垃圾邮件机器人的攻击,那么User-Agent比较很可能无法保护您,因为这些机器人通常会伪造一个通用的User-Agent字符串。在这种情况下,您需要采取更复杂的措施。如果需要用户输入,则像ReCaptcha这样的简单图像验证方案将起作用。
如果您想要过滤所有来自机器人的页面访问,不幸的是,如果机器人伪造其凭据,没有100%可靠的方法可以做到这一点。这只是互联网上令人烦恼的现实,Web管理员必须忍受它。

2
我发现了这个软件包,它正在积极开发中,我到目前为止非常喜欢它: https://github.com/JayBizzle/Crawler-Detect 它就是这么简单:
use Jaybizzle\CrawlerDetect\CrawlerDetect;

$CrawlerDetect = new CrawlerDetect;

// Check the user agent of the current 'visitor'
if($CrawlerDetect->isCrawler()) {
    // true if crawler user agent detected
}

// Pass a user agent as a string
if($CrawlerDetect->isCrawler('Mozilla/5.0 (compatible; Sosospider/2.0; +http://help.soso.com/webspider.htm)')) {
    // true if crawler user agent detected
}

// Output the name of the bot that matched (if any)
echo $CrawlerDetect->getMatches();

2

useragentstring.com提供了一个列表,您可以使用它来分析用户字符串:

$api_request="http://www.useragentstring.com/?uas=".urlencode($_SERVER['HTTP_USER_AGENT'])."&getJSON=all";
$ua=json_decode(file_get_contents($api_request), true);
if($ua["agent_type"]=="Crawler") die();

2
useragentstring.com已经不再在线,这是一个很好的例子,说明你不应该依赖第三方。 - Plixxer
useragentstring.com现已上线 - 我刚从他们的API获取了数据。这个答案中的链接已经失效了(如果你想要爬虫列表的话,链接现在是:http://www.useragentstring.com/pages/useragentstring.php?typ=Crawler)。 - Rasmus
你把返回的JSON当作关联数组,但是在json_decode中没有指定应该返回一个关联数组而不是一个JSON对象。我已经向你的帖子提交了编辑。 - Rasmus
@Rasmus:你能否修改我的回答呢? - rubo77

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