Perl/CGI研究室 'PERL-LABO'

Perl/CGI研究室 'PERL-LABO' TOPへ
戻る(History.Back)

クッキーで重複カウント回避

研究内容

クッキーをチェックして、同じ人がページを繰り返し見てもカウントされない アクセスカウンターを研究します。

詳細

今回作るアクセスカウンター

IPアドレスを使って重複を回避するカウンターは、 Aさん → Bさん → Aさん というように間に他の人が挟まると 同じ人のアクセスを重複してカウントしてしまうのでした。 そこで、IPアドレスに加えてクッキーによって重複カウントを回避するようにします。

結果

クッキー処理について

クッキーの読み書きについては、既に便利な関数を作ってあります。それを使いましょう。

クッキーの有効期限を利用します

一定時間内のアクセスをカウントしないようにする方法としては、 実際に前回アクセスした時間をクッキーに記録しておいて、 現在時刻との差をとることで経過時間を計算して、という方法がありますね。 でも都合のいいことに、 先に作ってある setcookie 関数はクッキーの有効期限を時間で指定できるようにしてあります。 ですから、自前で経過時間を計算するよりも、クッキーの有効期限の機能を利用すれば楽ですね。

ただし、クッキーの有効期限を利用する方法だと、 他にもなにかクッキーを使って保存しておきたいデータがある場合に困ります。 でもそれは今は考えなくてもいいですね。

重複カウントを回避する時間間隔について

それでは、重複カウントを回避する時間間隔をどれくらいにするか考えましょう。 例えば1日、24時間にする方法がありますね。 研究中のアクセスカウンターはトータルアクセスをカウントするのみですが、 日毎のアクセスを記録するアクセスカウンターというのもよくあります。 そう考えると、1回訪問してから1日以内のアクセスはカウントしないようにするというのは なかなか合理的な気もします。・・・が、1日、つまり24時間以内のアクセスは カウントしないということにすると、 最初に午後9時にアクセスして、次に次の日の午後8時にアクセスしてもアクセスは1回となりますね。 これはなんだか不自然な気がしませんか? ですから、24時間というのはちょっと長すぎる感じもします。 ということで、とりあえず半分の12時間ということにしましょう。

作成したCGIプログラム

counter.cgi (前回のCGIプログラムを修正しました)
#!/usr/bin/perl

require 'lock.pl';
require 'cookie.pl';

# クッキーによる重複カウント回避
# VISIT という名前のクッキーが 1 なら前回訪問から一定時間経っていません
%cookie = plab::getcookie();
$visit = 0;
if ($cookie{'VISIT'} == 1) {
	$visit = 1;
}
$cookie{'VISIT'} = 1;
plab::setcookie(12, %cookie);	# クッキーの有効期限は12時間です

print "Content-type: text/html\n\n";
print "<body style=\"margin:0;font-size:15px;\"><tt>";

$ip        = $ENV{'REMOTE_ADDR'};
$lockdir   = "lockdir";
$countfile = "count.cgi";

if (! plab::lock($lockdir)) {
	error();
}

open FILE, "< $countfile";

$count  = <FILE>;	# 1行目はカウント
$previp = <FILE>;	# 2行目はIPアドレス

close FILE;

# 前回と今回でIPアドレスが異なっていて、かつ、
# クッキーに前回訪問の記録が残っていなかったらカウントします
if ($previp ne $ip && ! $visit)
{
	++$count;

	if (! open(FILE, "> $countfile")) {
		plab::unlock($lockdir);
		error();
	}

	print FILE "$count\n";	# 1行目はカウント
	print FILE  $ip;		# 2行目はIPアドレス
	close FILE;
}

plab::unlock($lockdir);

$txt = sprintf("%05d", $count);
print $txt;
exit;

sub error
{
	print "?????";
	exit;
}

実行結果

カウンターです。このページに訪問してくれた方の数になると思います。

次のようなIFRAMEタグで表示しています。

<iframe src=counter.cgi width=45 height=20 frameborder=0></iframe>

解説

動きました

なんとか動きました。 IPアドレスをチェックする部分を外して、 クッキーでのみ重複チェックをするようにしたりして、 動作確認しています。ちゃんと動いているようです。

IPアドレスによる重複チェックだと問題があるからクッキーによる重複チェックを 追加したわけですが、それならIPアドレスによる重複チェックはもういらないんじゃないかな? と思いました。たぶん、いらないと思います。 でも、もしかしてクッキーを無効にしている訪問者様がおられるかも知れないので、 一応、IPアドレスによるチェックも残しています。

これでアクセスカウンターの重複回避としては合格レベルになったかな?

さらに改良を

アクセスカウンターの研究はまだまだ続きます。 現在はトータルのアクセス数だけしかカウントしていませんが、 これを昨日、今日、トータルというようにカウントしてみたり、 日毎、月毎、年毎、というように一定期間内のアクセスが分かるようにしてみたりする 研究が残ってます。そこまでできたら、アクセスカウンターとして合格ですね!

Perl/CGI研究室 'PERL-LABO' TOPへ
戻る(History.Back)

Copyright (c) 'PERL-LABO' All Rights Reserved.  リンクフリーです。