如何实现可靠的网页计数器?

时间:2009-07-29 17:51:26

标签: counter

实施网页计数器的好方法是什么?

从表面上看,这是一个简单的问题,但在处理搜索引擎抓取工具和机器人时,同一用户多次点击,刷新点击时会出现问题。

具体来说,确保链接不仅仅是用户通过反复点击“点击”的好方法是什么? IP地址?饼干?这两个都有一些缺点(IP地址不一定是唯一的,可以关闭cookie)。

另外,存储数据的最佳方法是什么?单独递增计数器或将每次单击作为记录存储在日志表中,然后偶尔进行汇总。

任何现场体验都会有所帮助,

+++ Rick ---

4 个答案:

答案 0 :(得分:4)

将IP地址与会话结合使用。计算每个新会话的IP地址,作为对您的计数器的一次点击。如果您认为自己需要查看数据,可以将此数据存储在日志数据库中。这对于计算您的网站获得最多流量,每天流量,每IP流量等非常有用。

答案 1 :(得分:2)

所以我根据这里的评论对此进行了一些讨论。我想出的是在一个简单的领域中计算一个计数器。在我的应用程序中,我有带有Views属性的代码段实体。

当查看代码段时,方法会过滤掉(白名单),希望浏览器应该是什么:

public bool LogSnippetView(string snippetId, string ipAddress, string userAgent)
{
    if (string.IsNullOrEmpty(userAgent))
       return false;

    userAgent = userAgent.ToLower();

    if (!(userAgent.Contains("mozilla") || !userAgent.StartsWith("safari") ||
        !userAgent.StartsWith("blackberry") || !userAgent.StartsWith("t-mobile") ||
        !userAgent.StartsWith("htc") || !userAgent.StartsWith("opera")))
        return false;

    this.Context.LogSnippetClick(snippetId, IpAddress);
}

然后,存储过程使用单独的表临时保存存储代码段ID,输入日期和IP地址的最新视图。记录每个视图,当新视图进入时,检查是否在最近2分钟内访问了此片段的相同IP地址。如果没有记录的话。

如果是新视图,则会记录视图(再次为SnippetId,IP,已输入),并在片段表上更新实际视图字段。

如果不是新视图,则会使用超过4分钟的任何记录清除表格。这应该会在任何时候在View日志表中产生最少数量的条目。

这是存储过程:

ALTER PROCEDURE [dbo].[LogSnippetClick]
    -- Add the parameters for the stored procedure here 
    @SnippetId AS VARCHAR(MAX),
    @IpAddress AS VARCHAR(MAX)          
   AS
   BEGIN

    SET NOCOUNT ON;

    -- check if don't allow updating if this ip address has already 
    -- clicked on this snippet in the last 2 minutes
    select Id from SnippetClicks 
        WHERE snippetId = @SnippetId AND ipaddress = @IpAddress AND 
              DATEDIFF(minute,  Entered, GETDATE() ) < 2      

     IF @@ROWCOUNT = 0  
     BEGIN              
        INSERT INTO SnippetClicks 
            (SnippetId,IpAddress,Entered) VALUES 
            (@SnippetId,@IpAddress,GETDATE())         
        UPDATE CodeSnippets SET VIEWS = VIEWS + 1 
            WHERE id = @SnippetId
     END
     ELSE
     BEGIN
        -- clean up
        DELETE FROM SnippetClicks WHERE DATEDIFF(minute,Entered,GETDATE()) > 4
     END
END

这似乎运作得相当好。正如其他人所说,这并不完美,但看起来它在初始测试中已经足够好了。

答案 2 :(得分:0)

如果您使用PHP,则可以使用会话来跟踪特定用户的活动。结合数据库,您可以跟踪特定IP地址的活动,您可以认为这些活动是同一个用户。

使用时间戳来限制命中(例如,假设每5秒不超过1次命中),并告知何时发生对站点的新“访问”(例如,如果最后一次命中超过10分钟)。

您可能会发现$ _SERVER []属性可帮助您检测机器人或访问者趋势(例如浏览器使用情况)。

编辑: 我跟踪了点击率和点击率之前的访问次数,将网页浏览量计为点击次数,以及创建新会话时的访问次数+1。它相当可靠(对于我用它的目的而言,它足够可靠。不支持cookie的浏览器(因此,不支持会话)和禁用会话的用户现在相当不常见,所以我不担心关于它,除非有理由过于准确。

答案 3 :(得分:0)

如果我是你,我首先会放弃我的计数器是准确的。像你说的那样,每个解决方案(例如cookie,IP地址等)往往都是不可靠的。因此,我认为您最好的选择是在系统中使用冗余:使用cookie,“Flash-cookies”(共享对象),IP地址(可能与用户代理一起使用)以及登录用户的用户ID。

您可以实现某种方案,其中任何未知客户端都被赋予唯一ID,该ID可以存储(希望)在客户端的计算机上并随每个请求重新传输。然后,您可以将IP地址,用户代理和/或用户ID(以及您能想到的任何其他内容)绑定到每个唯一ID,反之亦然。每次点击的时间戳和唯一ID都可以记录在某个地方的数据库表中,每次点击(至少每次点击进入您的网站)都可以通过或拒绝,具体取决于最后一次点击最近的同一个唯一ID。这对于短期点击爆发来说可能足够可靠,而且长期无论如何都不重要(对于点击问题,而不是页面计数器)。

友好机器人应该正确设置其用户代理,并且可以根据已知机器人用户代理列表进行检查(我在简单的Google搜索后找到一个here),以便正确识别并单独处理真实的人。