1. 程式人生 > >攜程智聯等網站百分之60%的訪問量都是爬蟲,對此我們應該怎麽辦

攜程智聯等網站百分之60%的訪問量都是爬蟲,對此我們應該怎麽辦

ace color min pub div 就是 簡單 服務器 sys

前言

爬蟲和反爬蟲日益成為每家公司的標配系統。

爬蟲在情報獲取、虛假流量、動態定價、惡意攻擊、薅羊毛等方面都能起到很關鍵的作用,所以每家公司都或多或少的需要開發一些爬蟲程序,業界在這方面的成熟的方案也非常多。

有矛就有盾,每家公司也相應的需要反爬蟲系統來達到數據保護、系統穩定性保障、競爭優勢保持的目的。

像安全與黑客從來都是相輔相成一樣。

爬蟲與反爬蟲也是在雙方程序員的鬥智鬥勇的過程不斷發展和成長的。

簡單的反爬蟲:

通過Headers反爬蟲

從用戶請求的Headers反爬蟲是最常見的反爬蟲策略。很多網站都會對Headers的User-Agent進行檢測,還有一部分網站會對Referer進行檢測(一些資源網站的防盜鏈就是檢測Referer)。如果遇到了這類反爬蟲機制,可以直接在爬蟲中添加Headers,將瀏覽器的User-Agent復制到爬蟲的Headers中;或者將Referer值修改為目標網站域名。對於檢測Headers的反爬蟲,在爬蟲中修改或者添加Headers就能很好的繞過。

基於用戶行為反爬蟲:

對於第二種情況,可以在每次請求後隨機間隔幾秒再進行下一次請求。有些有邏輯漏洞的網站,可以通過請求幾次,退出登錄,重新登錄,繼續請求來繞過同一賬號短時間內不能多次進行相同請求的限制。

參數加密:js 處理過程可以寫的很復雜,以至於爬蟲程序員沒法分析。

我們在和誰對抗?

    • 應屆畢業生(三月份爬蟲)
      三月份爬蟲通常和畢業生(本科生、碩士、博士等)有關,他們的爬蟲簡單粗暴,為了讓論文有數據支撐,根本不管服務器壓力,加上人數不可預測,很容易弄掛站點。

    • 創業小公司
      每年新增的創業公司很多,程序開發完後,缺少數據支撐,出於公司生死存亡的考慮,不斷爬取數據。

    • 不小心寫錯了沒人去停止的失控小爬蟲
      像知乎,攜程,財經等網站,可能高達60%的訪問量是爬蟲。你就算直接封殺,也無濟於事。他們可能根本爬不到任何數據了,除了http code是200以外,一切都是不對的,但由於托管後無人認領,仍然會依然孜孜不倦地爬取。

    • 成型的商業對手
      這是最大的對手,有技術,有錢,要什麽有什麽,如果和你死磕,你就只能硬著頭皮和他死磕。

    • 抽風的搜索引擎
      搜索引擎也有抽風的時候,而且一抽風就會導致服務器性能下降,請求量跟網絡攻擊沒有區別。

今天就說一說基本的反爬蟲,實現方式是拒絕頻繁訪問的ip,首先我們要實現 IHttpModule接口

using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.SessionState;
using System.Configuration;
namespace MyHttp
{
  public class UrlReWrite : IHttpModule
  {
    /// <summary>
    /// 單個IP最大連接限制數量
    /// </summary>
    private int rowCount = Convert.ToInt32(ConfigurationSettings.AppSettings["HttpRowCount"]);
    /// <summary>
    /// 指定區域時間範圍 單位分
    /// </summary>
    private int httpTime = Convert.ToInt32(ConfigurationSettings.AppSettings["HttpTime"]);
    public void Init(HttpApplication application)
    {
      application.BeginRequest += (new
         EventHandler(this.Application_BeginRequest));
      application.EndRequest += (new
         EventHandler(this.Application_EndRequest));
    }
    private void Application_BeginRequest(Object source, EventArgs e)
    {
      HttpApplication Application = (HttpApplication)source;
      HttpContext ctx = Application.Context;
      //IP地址
      string isIp = ctx.Request.UserHostAddress;
      if (ctx.Application["time"] == null)
      {
        ctx.Application["time"] = DateTime.Now;
      }
      else
      {
        DateTime isTime = (DateTime)ctx.Application["time"];
        int timeTract = Convert.ToInt32(DateTime.Now.Subtract(isTime).Minutes.ToString());
        if (timeTract > (httpTime - 1))
        {
          ctx.Application["time"] = null;
          ctx.Application["myip"] = null;
        }
      }
      if (ctx.Application["myip"] != null && ctx.Application["myip"] is CartIp)
      {
        CartIp cartIp = (CartIp)ctx.Application["myip"];
        cartIp.Insert(isIp);
        ctx.Application["myip"] = cartIp;
        if (cartIp.GetCount(isIp) > rowCount)
        {
          ctx.Response.Clear();
          ctx.Response.Close();
        }
      }
      else
      {
        CartIp cartIp = new CartIp();
        cartIp.Insert(isIp);
        HttpContext.Current.Application["myip"] = cartIp;
      }
    }
    private void Application_EndRequest(Object source, EventArgs e)
    {
    }
    public void Dispose()
    {
    }
  }
}

ListIp 類

using System;
using System.Collections.Generic;
using System.Text;
namespace MyHttp
{
  [Serializable]
  public class ListIp
  {
    private string ip;
    private int count;
    /// <summary>
    /// IP地址
    /// </summary>
    public string IP
    {
      get { return ip; }
      set { ip = value; }
    }
    /// <summary>
    /// 累加數量
    /// </summary>
    public int Count
    {
      get { return count; }
      set { count = value; }
    }
  }
  [Serializable]
  public class CartIp
  {
    public CartIp()
    {
      if (_listIp == null)
      {
        _listIp = new List<ListIp>();
      }
    }
    private List<ListIp> _listIp;
    public List<ListIp> _ListIp
    {
      get { return _listIp; }
      set { _listIp = value; }
    }
    /// <summary>
    /// 添加IP
    /// </summary>
    public void Insert(string ip)
    {
      int indexof = ItemLastInfo(ip);
      if (indexof == -1)
      {
        //不存在
        ListIp item = new ListIp();
        item.IP = ip;
        _listIp.Add(item);
      }
      else
      {
        _listIp[indexof].Count += 1;
      }
    }
    //判斷IP是否存在
    public int ItemLastInfo(string ip)
    {
      int index = 0;
      foreach (ListIp item in _ListIp)
      {
        if (item.IP == ip)
        {
          return index;//存在
        }
        index += 1;
      }
      return -1;//不存在
    }
    /// <summary>
    /// 獲得IP的數量
    /// </summary>
    /// <param name="ip"></param>
    /// <returns></returns>
    public int GetCount(string ip)
    {
      foreach (ListIp item in _ListIp)
      {
        if (item.IP == ip)
        {
          return item.Count;//存在
        }
      }
      return -1;//不存在
    }
  }
}

在web.config 配置訪問規則

<appSettings>
<add key="HttpRowCount" value="100"/>
<add key="HttpTime" value="10"/>
</appSettings>
<system.web>
  <httpModules>
  <add name="UrlReWrite" type="MyHttp.UrlReWrite"/>
 </httpModules>
</system.web>

對於這種方式的反反爬蟲只能是放慢爬蟲速度,防止被拉入黑名單!。。

攜程智聯等網站百分之60%的訪問量都是爬蟲,對此我們應該怎麽辦