質問
Webページカウンターを実装する良い方法は何ですか?
表面的にはこれは単純な問題ですが、検索エンジンのクローラーとロボット、同じユーザーによる複数のクリック、更新クリックを処理するときに問題になります。
具体的には、ユーザーが繰り返しクリックするだけでリンクが「クリックアップ」されないようにする良い方法は何ですか? IPアドレス?クッキー?どちらにもいくつかの欠点があります(IPアドレスは必ずしも一意ではなく、Cookieをオフにできます)。
また、データを保存する最良の方法は何ですか?カウンターを個別にインクリメントするか、各クリックをログテーブルのレコードとして保存し、ときどき要約します。
どんなライブエクスペリエンスも役立ちます。
+++リック---
解決 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、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
これはかなりうまくいくようです。他の人が述べたように、これは完璧ではありませんが、初期テストでは十分に良いようです。
他のヒント
セッションと組み合わせてIPアドレスを使用します。 IPアドレスのすべての新しいセッションを、カウンターに対する1回のヒットとしてカウントします。このデータを調べる必要があると思われる場合は、このデータをログデータベースに保存できます。これは、サイトが最も多くのトラフィックを取得する時期、1日あたり、IPごとのトラフィック量などを計算するのに役立ちます。
PHPを使用する場合、セッションを使用して特定のユーザーからのアクティビティを追跡できます。データベースと組み合わせて、特定のIPアドレスからのアクティビティを追跡することができます。これは、同じユーザーであると想定できます。
タイムスタンプを使用してヒットを制限し(たとえば、5秒あたり1ヒットを超えないことを想定)、新しい「訪問」がいつ発生するかを通知します。サイトへのアクセスが発生します(最後のヒットが10分以上前の場合など)。
ボットや訪問者の傾向(ブラウザの使用状況など)を検出するのに役立つ$ _SERVER []プロパティがあります。
編集: ヒット&amp;を追跡しました前の訪問数、ページビューをヒットとしてカウントし、新しいセッションが作成されたときの訪問数に+1を付けます。かなり信頼性が高かった(私が使用した目的に対して十分に信頼性が高い。Cookieをサポートしない(したがってセッションをサポートしない)ブラウザーとセッションを無効にするユーザーは最近ではあまり一般的ではないので、心配しないでください)過度に正確である理由がない限り、それについて。
私があなただったら、そもそも正確であることをあきらめたでしょう。あなたが言ったように、すべてのソリューション(例:Cookie、IPアドレスなど)は信頼できない傾向があります。したがって、最善の策はシステムで冗長性を使用することだと思います。Cookie、「Flash Cookie」を使用します。 (共有オブジェクト)、IPアドレス(おそらくユーザーエージェントと組み合わせて)、およびログインしているユーザーのユーザーID。
未知のクライアントに一意のIDが与えられ、クライアントのマシンに(できれば)保存され、リクエストごとに再送信されるようなスキームを実装できます。それから、IPアドレス、ユーザーエージェント、ユーザーID(およびあなたが考えることができるもの)をすべての一意のIDに結び付けることができます。すべてのクリックのタイムスタンプと一意のIDは、どこかのデータベーステーブルに記録され、各一意のIDに対するラストクリックの最新度に応じて、各クリック(少なくとも、Webサイトへの各クリック)を許可または拒否できます。これはおそらく、短期的なクリックバーストに対しては十分に信頼性があり、長期的にはそれほど重要ではありません(ページカウンターではなく、クリックアップの問題に対して)。
使いやすいロボットは、ユーザーエージェントを適切に設定する必要があり、既知のロボットユーザーエージェントのリストと照合できます(ここを簡単なGoogle検索の後に))適切に識別し、実在の人物から個別に処理するため。