【问题标题】:How to Implement a Reliable Web Page Counter?如何实现可靠的网页计数器?
【发布时间】:2009-07-29 17:51:25
【问题描述】:

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

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

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

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

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

+++ 瑞克 ---

【问题讨论】:

  • 你在问一个非常难的问题。想想谷歌是如何处理点击欺诈问题的,你就会知道你的问题有多大。
  • 我同意.. 这不是一个简单的问题.. 虽然我一直想知道为什么 Web 服务器不提供好的分析解决方案。我说把 Google Analytics 打在上面,然后就完成了……除非你想重新发明公认的坏轮子。
  • 明白,但这就是我在这里问的原因:-}。我并不是真的在这里进行分析,而是在 SO 上使用与此处类似的计数器,以至少半可靠地显示观看次数。
  • 这是瑞克·斯特拉尔吗?

标签: counter


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    所以我根据这里的 cmets 玩了一下。我想出的是在一个简单的领域计算一个计数器。在我的应用中,我有带有 Views 属性的代码 sn-p 实体。

    当查看一个 sn-p 时,一个方法过滤掉(白名单)应该是浏览器:

    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);
    }
    

    然后存储过程使用一个单独的表来临时保存最新的视图,其中存储了 sn-p Id、输入的日期和 IP 地址。每个视图都被记录下来,当一个新视图出现时,它会检查相同的 IP 地址是否在过去 2 分钟内访问了这个 sn-p。如果是这样,则不会记录任何内容。

    如果是新视图,则会记录该视图(同样是 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
    

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

    【讨论】:

      【解决方案3】:

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

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

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

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

      【讨论】:

      • IP 地址在长期内并不可靠
      • 使用 ASP.NET (MVC),虽然 Session 是一个选项,但它无助于机器人的无 cookie 访问。 Plus 会话有一些开销,否则这个应用程序不需要。
      【解决方案4】:

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

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

      友好的机器人应该适当设置它们的用户代理,并且可以对照已知机器人用户代理列表进行检查(我在简单的 Google 搜索后找到了一个 here),以便正确识别并与真人分开处理.

      【讨论】:

      • 谢谢卡梅伦。这就是我现在所处的位置。问题的重点是看看是否有更好的方法可用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-26
      • 2014-11-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多