7

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

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

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

还有什么是存储数据的最佳方式?单独增加一个计数器或将每次点击作为记录存储在日志表中,然后偶尔进行汇总。

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

+++ 瑞克 ---

4

4 回答 4

4

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

于 2009-07-29T18:11:11.143 回答
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 地址的最新视图。每个视图都会被记录下来,当一个新视图出现时,它会检查相同的 IP 地址是否在过去 2 分钟内访问了这个片段。如果是这样,则不会记录任何内容。

如果是新视图,则会记录视图(同样是 SnippetId、IP、Entered),并且在 Snippets 表上更新实际的 Views 字段。

如果它不是一个新视图,那么该表将被清理,并记录任何超过 4 分钟的视图。这应该会导致在任何时候查看日志表中的条目数量最少。

这是存储过程:

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

这似乎工作得很好。正如其他人所提到的,这并不完美,但在初始测试中看起来已经足够好了。

于 2009-07-30T19:43:46.627 回答
0

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

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

友好的机器人应该适当地设置他们的用户代理,并且可以根据已知的机器人用户代理列表(我在简单的谷歌搜索后在这里找到一个)进行检查,以便正确识别和处理与真人分开。

于 2009-07-29T18:19:27.347 回答
0

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

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

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

编辑:我之前跟踪过点击次数和访问次数,将页面查看计为点击次数,并在创建新会话时为访问次数 +1。它相当可靠(对于我使用它的目的来说已经足够可靠了。不支持 cookie 的浏览器(因此,不支持会话)和禁用会话的用户现在相当少见,所以我不会担心除非有理由过于准确。

于 2009-07-29T17:55:16.843 回答