互联网服务 2012 年 5 月 31 日

禁止某些搜索机器人和特定IP用户访问网站

本文介绍了一种屏蔽AhrefsBot机器人访问网站的方法,避免其增加带宽和服务器负担,节能环保。虽然最简单的robots.txt规则和直接将AhrefsBot的IP加入Apache的禁止访问名单也可以达到屏蔽的效果,但对于不遵守robots.txt规则的蜘蛛和动态IP无效。因此,作者提出使用php代码来屏蔽的方法,可以使用关键字屏蔽和IP屏蔽,灵活性更高。文章给出了相关代码实现,可供读者参考。
最近发现一个叫AhrefsBot的机器人特别勤快,每天都数次访问我的网站,并且不遵守robotx.txt规则,几乎采集了网站的每个页面,但却没带来任何流量。上官网去看了下发现Ahrefs貌似是一家做搜索引擎优化的网站,对于小站来说,只会增加带宽和服务器负担,没有任何好处。基于节能环保的原则,完全可以把AhrefsBot屏蔽掉。
Ahrefsbot visit log
屏蔽方法很多,比如最简单的robots.txt规则:

user-agent: AhrefsBot
disallow: /

除了使用robots.txt,直接将AhrefsBot的IP加入Apache的禁止访问名单也可以达到屏蔽的效果。
上面两种方法都不太灵活,比如robots.txt,对于有些不遵守robots.txt规则的蜘蛛根本无效,搜狗蜘蛛就直接无视robots.txt,即使你将它disallow掉它还是照样勤快地爬掉你的流量;而htaccess加入ip对于动态ip则无效了,并且ip数太多会加重服务器负担。
下面我们介绍一种使用php代码来屏蔽的方法,可以使用关键字屏蔽和IP屏蔽。效果和htaccess一样。
原理:
因为每一个访问者(包含robots)都具有User Agent 和IP定义,我们可以对访问者的User Agent 字段和IP进行正则匹配,将带有关键字的User Agent 和在黑名单的IP屏蔽掉。
使用代码的方式虽然麻烦些,但是可以做的很灵活,比如我们还可以加上手机用户重定向等功能。 如果你的博客也经常遇到一些莫名的扫描造成404错误,那就别犹豫了,使用代码将这些不太友好的客人加入黑名单吧。 下面我们写一些简单的代码来实现通过User Agent 和访客ip屏蔽恶意访客的功能。
恶意访问
STEP 1: 定义两个函数,判断用户的User Agent 和 IP是否在我们的黑名单中:
function match_visitors_by_ua($myua) { 
 
    $ua_blacklist = array( 
                'AhrefsBot', 
                'Mail\.RU', 
                'Sogou web spider', 
                //'Firefox', 
                ); 
                 
    if (preg_match("/(" . implode('|', $ua_blacklist) . ")/", $myua) ) { 
        return true; 
    } 
    else { 
        return false; 
    } 
} 
 
function match_visitors_by_ip($myip) { 
 
    $ip_blacklist = array( 
                '255\.255\.255\.255', /* just a example */ 
                '61\.187\.98\.69', 
                ); 
                 
    if ( preg_match("/(" . implode('|', $ip_blacklist) . ")/", $myip) ) { 
        return true; 
    } 
    else { 
        return false; 
    } 
} 
上面的User Agent 黑名单和ip黑名单可以任意添加条目,注意特殊符号需要转义,如果你不太清楚如何操作,建议参考一些正则表达式方面的资料。
STEP 2: 调用这两个函数判断是否应该屏蔽访问者
如果访问者在黑名单中,那么就返回一个403错误并退出,这样以后的代码就不会执行,节省了一些服务器资源.当然,你也可以把403错误换成401 未授权、404 未找到等错误。
function do_filter_visitors() { 
 
    if(isset($_SERVER["HTTP_USER_AGENT"]) && match_visitors_by_ua($_SERVER["HTTP_USER_AGENT"]) ) { 
        header('HTTP/1.1 403 Forbidden'); 
        exit(); 
    } 
     
    if(isset($_SERVER["REMOTE_ADDR"]) && match_visitors_by_ip($_SERVER["REMOTE_ADDR"]) ) {   
        header('HTTP/1.1 403 Forbidden'); 
        exit(); 
    } 
} 
 
add_action('init','do_filter_visitors'); 
这样每次WordPress初始化的时候都会先判断访问者是否在黑名单中,如果在就直接返回一个403错误告知来访者无权访问.
把上面的代码加到主题的functions.php文件就可以了,下面是屏蔽掉Firefox的截图,可以看到浏览器收到一个403错误,没有任何其它内容。
block test
附上几个可能给服务器增加负担却不带来流量或很少流量的爬虫名称,你可以选择性地加入黑名单:
  • Yandex: 俄罗斯门户网站的机器人,只索引俄语网站;
  • Mail.RU: 俄罗斯另一个门户网站的机器人,同样不索引中文页面;
  • JikeSpider: 即刻搜索;
  • Sogou web spider: 搜狗的爬虫,特别勤快,不知道是不是由于糟糕的算法,索引量特别小,并且不遵守robots.txt规则,建议屏蔽。