V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
Tianpu
V2EX  ›  分享创造

自动封锁采集器、自动评论、垃圾蜘蛛

  •  
  •   Tianpu · 2014-08-06 17:55:52 +08:00 · 3514 次点击
    这是一个创建于 3555 天前的主题,其中的信息可能已经有所发展或是发生改变。
    被折腾的受不了,大致实现了访问频率稍微高就自动封掉访问,似乎是封一个小时什么比较好,不想为恶意访问的人考虑太多,所以自动解封就不实现了

    大致上要耗费1ms的执行时间

    实现:php mysql memcached

    思路:正常蜘蛛白名单,读到memcached里去,其它的计划任务再检测,频率太高就封掉。

    文件结构:
    bots.txt 蜘蛛IP数据
    white.txt 需要补充到白名单的数据
    inc.php需要包含到动态页面的函数
    block.php计划任务执行脚本

    ---------bots.txt-----------------
    //googlebot
    64.233.160.0-64.233.191.255
    66.102.0.0-66.102.15.255
    66.249.64.0-66.249.95.255
    72.14.192.0-72.14.255.255
    74.125.0.0-74.125.255.255
    209.85.128.0-209.85.255.255
    216.239.32.0-216.239.63.255

    //bingbot
    64.4.0.0-64.4.63.255
    65.52.0.0-65.55.255.255
    131.253.21.0-131.253.47.255
    157.54.0.0-157.60.255.255
    207.46.0.0-207.46.255.255
    207.68.128.0-207.68.207.255

    //baiduspider
    180.76.5.0-180.76.5.255
    180.76.6.0-180.76.6.255
    220.181.108.0-220.181.108.255
    123.125.67.0-123.125.67.255
    123.125.71.0-123.125.71.255

    //sogouspider
    218.30.103.0-218.30.103.255

    //yandexbot
    199.21.99.0-199.21.99.255

    针对用户这么写:
    function initipdata(){
    global $memd;
    $ips = array();
    $key = 'bots.txt';
    $ips = $memd->get($key);
    if(empty($ips)){
    $temp = explode("\n",file_get_contents(dirname(__FILE__).'/bots.txt'));
    foreach($temp as $raw){
    $raw = trim($raw);
    if(!empty($raw) && substr($raw,0,2)!='//'){
    $ra = explode('-',$raw);
    if(long2ip(ip2long($ra[0]))==$ra[0] && long2ip(ip2long($ra[0]))==$ra[0]){
    $ips[] = array('s'=>ip2long($ra[0]),'e'=>ip2long($ra[1]));
    }
    }
    }
    if(!empty($ips)) $memd->set($key,$ips,86400);
    }
    return $ips;
    }
    function ipwarn(){
    global $conn,$memd;
    $check = false;
    $ips = initipdata();
    $key = $_SERVER['REMOTE_ADDR'];
    $raw = ip2long($key);
    foreach($ips as $ip){
    if(!$check && $raw>=$ip['s'] && $raw<=$ip['e']){
    $check = true;
    }
    }
    if(!$check){
    $num = 0;
    $num = $memd->get($key);
    $num = $num+1;
    $memd->set($key,$num,120);
    if($num>30){
    mysql_query('insert into `_zwarn` (`ip`,`time`) values (\''.addslashes($key).'\',\''.addslashes(time()).'\');',$conn);
    }
    }
    }

    然后做个计划任务

    function show($s){
    echo $s."\r\n";
    }
    function getipnum($key){
    global $memd;
    $num = 0;
    $num = $memd->get($key);
    return $num;
    }
    function gethost($ip){
    $r = '';
    $r = gethostbyaddr($ip);
    return $r;
    }
    function checkip($ip,$host){
    $white = array('.googlebot.com','.baidu.com','.yandex.com','.sogou.com','.bing.com','.msn.com');
    $check = true;
    if(!empty($host) && $ip!==$host){
    $addr = gethostbyname($host);
    if($addr==$ip && str_ireplace($white,'',$host)!=$host){
    $check = false;
    }
    }
    return $check;
    }
    $meta = array();
    $sql = 'select * from `_zwarn`;';
    $rs = mysql_query($sql,$conn);
    while($row=mysql_fetch_object($rs)){
    $meta[($row->ip)] = $row->time;
    }
    foreach(array_keys($meta) as $addr){
    $data = array();
    $data['addr'] = $addr;
    $data['host'] = gethost($data['addr']);
    $data['bool'] = checkip($data['addr'],$data['host']);
    $data['last'] = 30;
    $data['curr'] = getipnum($data['addr']);
    $data['time'] = time()-$meta[($data['addr'])];
    $data['rate'] = ($data['curr']-$data['last'])/$data['time'];
    foreach(array_keys($data) as $key){
    show($key.': '.$data[$key]);
    }
    if($data['bool']){
    if($data['rate']>0.5 || $data['curr']>60){
    show('iptables -I INPUT -s '.$data['addr'].'/32 -j DROP');
    passthru('iptables -I INPUT -s '.$data['addr'].'/32 -j DROP');
    mysql_query('insert into `_zblock` (`ip`,`host`) values (\''.addslashes($data['addr']).'\',\''.addslashes($data['host']).'\');');
    mysql_query('delete from `_zwarn` where `ip`=\''.addslashes($data['addr']).'\';');
    if($data['curr']>0){
    $memd->set($data['addr'],0,120);
    }
    }
    if($data['curr']<1){
    mysql_query('delete from `_zwarn` where `ip`=\''.addslashes($data['addr']).'\';');
    }
    }
    else{
    file_put_contents(dirname(__FILE__).'/white.txt',$data['addr']."\r\n",FILE_APPEND);
    mysql_query('delete from `_zwarn` where `ip`=\''.addslashes($data['addr']).'\';');
    }
    show('');
    }
    13 条回复    2014-08-07 14:34:50 +08:00
    X-Force
        1
    X-Force  
       2014-08-06 18:57:58 +08:00
    收藏备用,给楼主加油……
    dong3580
        2
    dong3580  
       2014-08-06 19:18:18 +08:00
    先收藏备用,
    请教一下楼主,模拟浏览器请求,带上全部user-agent,不频繁,变ip,恐怕效果不佳吧?
    Tianpu
        3
    Tianpu  
    OP
       2014-08-06 21:14:50 +08:00
    @dong3580 如果跟真实访问类似,实在没什么好办法
    overlords
        4
    overlords  
       2014-08-06 22:25:05 +08:00
    @dong3580 这么多的IP哪里搞啊?
    iannil
        5
    iannil  
       2014-08-07 00:23:41 +08:00
    变ip的方法有,但成本一般比较高,常见的方法:
    1、多条家用线路重拨获得新ip,这种比较简单
    2、购置大量的虚拟机,然后通过proxy中转请求来达到切换ip的目的,这种比较复杂,因为有个路由器和防火墙的关系,需要proxy主动向调度中心发起请求。
    3、使用VPN拨号
    liuchen9586
        6
    liuchen9586  
       2014-08-07 00:48:47 +08:00
    收藏备用
    66CCFF
        7
    66CCFF  
       2014-08-07 01:25:16 +08:00
    @iannil 低成本方法: 淘宝上大量代理
    iannil
        8
    iannil  
       2014-08-07 01:29:18 +08:00
    @66CCFF 代理成本也不低,因为你需要雇佣技术人员针对这些代理写一套检测有效性、分配ip、联合调度等内容的程序。另外,代理也有相同的问题,就是如果要绕过防火墙,必须要由proxy,也就是代理服务器主动发起连接。
    yangqi
        9
    yangqi  
       2014-08-07 01:33:24 +08:00
    fail2ban结合nginx/apache log就能搞定吧
    Tianpu
        10
    Tianpu  
    OP
       2014-08-07 08:02:18 +08:00
    @iannil TOR
    dong3580
        11
    dong3580  
       2014-08-07 09:48:53 +08:00
    @overlords
    @iannil
    就算不是变ip,只需要前面几种,爬点东西都会带上全部的user-agent,而且都只开一个线程,访问基本上都是爬完整个page几分钟,有时候几个页面睡会儿,长期挂住。这样根本没法屏蔽。个人觉得防止爬虫太难了。
    iannil
        12
    iannil  
       2014-08-07 14:30:53 +08:00
    @dong3580 是的, 如果完全不考虑效率问题,操作速度以及操作习惯完全与人一致的爬虫是无法屏蔽的。
    但是对爬虫来说,效率是必定要考虑的,因为如果爬虫速度比人还慢,就会丢失了一半的价值,另一半的价值是爬虫不知疲倦没有情绪。
    iannil
        13
    iannil  
       2014-08-07 14:34:50 +08:00
    @Tianpu tor是个好办法,但tor的问题在于连接tor的成本过高以及速度上的限制,无法稳定高速的进行抓取操作。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2596 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 35ms · UTC 13:32 · PVG 21:32 · LAX 06:32 · JFK 09:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.