我可以用哪些方法来检测机器人?

本文关键字:检测 检测机 机器人 方法 我可以 | 更新日期: 2023-09-27 18:03:23

仅仅因为软件是自动化的并不意味着它会遵守您的robots.txt。什么是一些可用的方法来检测当有人爬或ddose你的网站?假设您的站点有100到1000个页面,值得抓取或DDOSing。

我有一个愚蠢的想法,可能行不通:给每个用户一个具有唯一值的cookie,并使用cookie来知道何时有人发出第二次/第三次/等等请求。这可能不起作用,因为爬虫可能不接受cookie,因此在此方案中,机器人对每个请求都看起来像一个新用户。

有人有更好的主意吗?

我可以用哪些方法来检测机器人?

您可以在您的页面中放置最终用户不可见或无法点击的链接。许多机器人只是跟随所有链接。一旦有人请求其中一个链接,你几乎肯定有一个爬虫/机器人。

Project Honey Pot保存了一个"坏"机器人的列表。

这是我写的一个类来联系他们的web服务。你将不得不修改一些,因为我有几个专有库在它,但大多数情况下,它应该是好的。有时他们的服务会发回错误,但它确实有助于减少一些不良流量。

using System;
using System.Linq;
using System.Net;
using System.Xml.Linq;
using SeaRisenLib2.Text;
using XmlLib;
/// <summary>
/// Summary description for HoneyPot
/// </summary>
public class HoneyPot
{
    private const string KEY = "blacklistkey"; // blacklist key - need to register at httpbl.org to get it
    private const string HTTPBL = "dnsbl.httpbl.org"; // blacklist lookup host
public HoneyPot()
{
}
public static Score GetScore_ByIP(string ip)
{
    string sendMsg = "", receiveMsg = "";
    int errorCount = 0; // track where in try/catch we fail for debugging
    try
    {
        // for testing: ip = "188.143.232.31";
        //ip = "173.242.116.72";
        if ("127.0.0.1" == ip) return null; // localhost development computer
        IPAddress address;
        if (!IPAddress.TryParse(ip, out address))
            throw new Exception("Invalid IP address to HoneyPot.GetScore_ByIP:" + ip);
        errorCount++; // 1
        string reverseIP = ip.ToArray('.').Reverse().ToStringCSV(".");
        sendMsg = string.Format("{0}.{1}.{2}", KEY, reverseIP, HTTPBL);
        errorCount++; // 2
        //IPHostEntry value = Dns.GetHostByName(sendMsg);
        IPHostEntry value = Dns.GetHostEntry(sendMsg);
        errorCount++; // 3
        address = value.AddressList[0];
        errorCount++; // 4
        receiveMsg = address.ToString();
        errorCount++; // 5
        int[] ipArray = receiveMsg.ToArray('.').Select(s => Convert.ToInt32(s)).ToArray();
        errorCount++; // 6
        if (127 != ipArray[0]) // error
            throw new Exception("HoneyPot error");
        errorCount++; // 7
        Score score = new Score()
        {
            DaysSinceLastSeen = ipArray[1],
            Threat = ipArray[2],
            BotType = ipArray[3]
        };
        errorCount++; // 8
        return score;
    }
    catch (Exception ex)
    {
        Log.Using("VisitorLog/HoneyPotErrors", log =>
        {
            log.SetString("IPrequest", ip);
            log.SetString("SendMsg", sendMsg, XmlFile.ELEMENT);
            log.SetString("RecvMsg", receiveMsg, XmlFile.ELEMENT);
            log.SetString("Exception", ex.Message, XmlFile.ELEMENT);
            log.SetString("ErrorCount", errorCount.ToString());
        });
    }
    return null;
}
// Bitwise values
public enum BotTypeEnum : int
{
    SearchEngine = 0,
    Suspicious = 1,
    Harvester = 2,
    CommentSpammer = 4
}
public class Score
{
    public Score()
    {
        BotType = -1;
        DaysSinceLastSeen = -1;
        Threat = -1;
    }
    public int DaysSinceLastSeen { get; internal set; }
    public int Threat { get; internal set; }
    /// <summary>
    /// Use BotTypeEnum to understand value.
    /// </summary>
    public int BotType { get; internal set; }
    /// <summary>
    /// Convert HoneyPot Score values to String (DaysSinceLastSeen.Threat.BotType)
    /// </summary>
    /// <returns></returns>
    public override string ToString()
    {
        return string.Format("{0}.{1}.{2}",
            DaysSinceLastSeen,
            Threat,
            BotType);
    }
    public static explicit operator XElement(Score score)
    {
        XElement xpot = new XElement("HoneyPot");
        if (null != score)
        {
            if (score.DaysSinceLastSeen >= 0)
                xpot.SetString("Days", score.DaysSinceLastSeen);
            if (score.Threat >= 0)
                xpot.SetString("Threat", score.Threat);
            if (score.BotType >= 0)
                xpot.SetString("Type", score.BotType);
            foreach (BotTypeEnum t in Enum.GetValues(typeof(BotTypeEnum)))
            {
                // Log enum values as string for each bitwise value represented in score.BotType
                int value = (int)t;
                if ((value == score.BotType) || ((value & score.BotType) > 0))
                    xpot.GetCategory(t.ToString());
            }
        }
        return xpot;
    }
    public static explicit operator Score(XElement xpot)
    {
        Score score = null;
        if (null != xpot)
            score = new Score()
            {
                DaysSinceLastSeen = xpot.GetInt("Days"),
                Threat = xpot.GetInt("Threat"),
                BotType = xpot.GetInt("Type")
            };
        return score;
    }
}
/// <summary>
/// Log score value to HoneyPot child Element (if score not null).
/// </summary>
/// <param name="score"></param>
/// <param name="parent"></param>
public static void LogScore(HoneyPot.Score score, XElement parent)
{
    if ((null != score) && (null != parent))
    {
        parent.Add((XElement)score);
    }
}

}

虽然从技术上讲,它不会"检测"bot爬虫,但我有一个有趣的方法来阻止它们。我的方法是创建一个IIS过滤器或Apache插件。你要做的是加密你所有的html, asp, php等…页面。唯一未加密的页面是索引页面。索引页只是安装一个带有加密公钥的cookie,然后重定向到第二个索引页。然后,IIS过滤器或Apache插件将检查每个访问者,以确保他们拥有这个cookie。如果是这样,过滤器将解密请求的页面,然后将页面传递到web服务器进行处理。

这种方法将允许普通访问者查看您的网页,但如果拒绝cookie的bot试图读取您的网页,它们将被加密。

黑名单可能不是一个好方法,最好有一个已知机器人的白名单,允许每秒超过一定数量的点击。如果不在白名单上的人每秒点击次数太多,就开始中断他们的连接几秒钟。这将有助于防止滥用,仍然让未知的机器人扫描你的网站(尽管比你认为重要的慢得多)。

你可以把违规者记录下来,看看谁是反复违反规则的:)