Perl/CGI研究室 'PERL-LABO'

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

重複カウント排除の強化

研究内容

アクセスカウンターで正しく訪問者の数を数えるには、 「重複カウントの排除」がとっても重要です。 これまで作ったカウンターも重複カウントの排除機能がありましたが、 これをもっと強化してみましょう。

詳細

重複カウントとは

重複カウントというのは、同じ人が何度もカウントされてしまうことです。 例えばF5キーを押してリロードしたとか、 他のページに行ってからトップページに戻ってきたとか、 あるいは、全てのページにカウンターが仕込んである場合は、ページを開くたびにカウントが増えてしまいます。 これ、カウントがどんどん増えていくという点では嬉しい気持ちもありますが、 「今日は何人来てくれたのかな?」ということが知りたいときは、正確な人数では無くなってしまうので困ってしまうわけです。 重複カウントを排除すると、正しい訪問者数を知ることができます。

重複カウントを除く方法

重複カウントを排除する方法としては、クッキーを使う方法と、IPアドレスを使う方法がありました。 (逆に、この2つ以外には方法が無いみたいです。)

クッキーを使う方法というのは、最初の訪問でカウントアップしたとき、クッキーに「今日はカウントアップしました」という 情報を記録することで、1日1回だけカウントするようにする方法です。

IPアドレスを使う方法というのは、それまでの訪問者のIPアドレスを記録しておいて、同じIPアドレスの場合は 1日1回だけカウントするという方法です。

これまでの当サイトのアクセスカウンターの問題点

これまでに当サイトで作って、使っているアクセスカウンターでも、 クッキーとIPアドレスの両方で重複カウントを排除していました。 しかし、完璧なものではありませんでした。 IPアドレスのチェックを、「直前の訪問者と同じIPアドレスの場合はカウントアップしない」としていたのです。 最初から分かっていたのですが、次のようなケースでは重複してカウントがされてしまいます。

・クッキーが無効になっている訪問者が、(クッキーによる重複カウント排除が効かない)
・しばらく経ってから訪問した(間に他の人が挟まると、IPによる重複カウント排除が効かない)

例えば、クッキーが無効の人が、午前中に1回、午後に1回訪問すると、カウントが2増えてしまいます。

これまでの当サイトのアクセスカウンターの、実際のところ

さて、そうは言っても、「クッキーが無効」かつ「間に他の人が挟まる」というのは、 (特にアクセスが少ないうちは)滅多に起こらないことだと思います。 ですから、それほど気にしなくても大丈夫のはずでした。 でも、実際のところ、どうなのでしょうか? 重複カウントは、ちゃんと排除できているのかな? ということで、「カウントアップした訪問者のIPアドレスを別ファイルに記録する」というオプション機能を 付けて、動作確認を行ってみました。結果は…うーん、微妙に重複カウントされちゃっていました(^^; 5%程度ですが、実際の訪問者数よりもカウントが多かったようです。

IPアドレスでの重複チェックを強化

それでは、より正確な訪問者数を知るために、改良をしましょう。 IPアドレスでの重複チェックを強化します。 その日にカウントアップしたIPアドレスを全て記録しておいて、 同じIPアドレスに対してはカウントアップしないようにします。 これまでのように「直前のIPアドレスと同じかどうか」ではなく、 「既にカウントアップしたかどうか」での判定ですから、かなり厳密になりますね。

さて、ここで注意点があります。1日のアクセス全てで訪問者のIPアドレスを記録して、 重複もチェックするとなると、CPU負荷が増えますよね。 これまで、IPアドレスのチェックを直前のIPアドレスとの比較のみにしていたのは、 負荷を抑えるためという理由もありました。 では、できるだけ負荷を抑えつつIPアドレスの重複チェックを厳密に行うにはどうしたらいいのかな… と考えると、負荷の軽い順に、段階的にチェックしていくのが有効だということに気がつきました。 具体的には、次のような処理になります。

1.クッキーによって重複チェックを行います。
2.直近10個くらいのIPアドレスと比較して重複チェックを行います。
3.その日1日全てのIPアドレスと比較して重複チェックを行います。

3の処理を行えば、2の処理をしなくても同じIPアドレスの重複カウントは100%完璧に排除できます。 でも、毎回3の処理をしていると負荷が大きいので、負荷の軽い2の処理を先に行うっていうのがミソです。 カウンターの場合、今日/昨日/トータルの3つの数字を表示するために、ほぼ同時に3回のCGIプログラムへの アクセスが発生したりしますが、そういうアクセスは、2の重複チェックで排除できますので、 負荷のやや大きな3の処理を行わなくて済みます。

さらにもう1つの改良ポイントなのですが、 2の処理で、これまで直前1個のみとの比較だったのを、直近10個くらいとの比較に拡張します。 これはそれほど負荷が増えずに行うことができます。具体的には、 これまで「IPアドレス」という文字列を記録していたのを、 「IPアドレス1/IPアドレス2/IPアドレス3/IPアドレス4/…」のような複数のIPアドレスをつなげて記録するように します。 この中に特定のIPアドレスが存在するかどうかは、単純な文字列探索、例えばindex関数で調べられます。 新しいIPアドレスは、文字列の先頭に追加して、同時に末尾のIPアドレスを削除します。 そのあたりの処理は、配列を使えばできそうですね。

3は、今回強化するチェック処理ですね。 別のファイルに1行につき1つのIPアドレスを書き込んでおいて、比較チェックすればOKです。

結果

当サイトのアクセスカウンターは、こうしてかなり厳密に重複カウントを排除しております。 今回の改良で、カウントの値が少し減っちゃったのが寂しいですね(^^;

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

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