Perl/CGI研究室 'PERL-LABO'

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

ページビューカウンターの作成(まずはカウントから)

【セキュリティソフトの警告についてのお知らせ】
ここで作成したCGIプログラムは、サイズ1x1のIFRAMEタグで呼び出すようにしています。 2008年10月現在、セキュリティソフトであるウイルスバスターで、サイズ1x1のIFRAMEは 「セキュリティの驚異 - Possible_Hifrm-5」という警告が出るようになってしまいました。 サイズ1x1のIFRAMEでCGIプログラムを呼び出すやり方は、簡単にできて便利なのですが、事実上、やってはいけないということですね。 ということで、このページを含め、以降のページでは、セキュリティソフトから警告が表示される可能性があります。 ご容赦ください。 セキュリティソフトからの警告が出る場合は、 セキュリティソフトの警告を止めるか、無視するか、以下のページは参照せずに他の記事をお楽しみください。 なお、CGIプログラムは、画像ファイルとして呼び出し、CGIプログラムは1x1の透過gif画像を返すのが 一般的ですが、このページを作成時点では、説明上IFRAMEを使った方が簡単だったために、そのような内容になっています。 いずれ警告が出ない形に修正したいと思います。

研究内容

どのページが何回閲覧されたかカウントするCGIプログラム、ページビューカウンターを作りましょう。

詳細

なぜ作りたいかというと

どのページが何回開かれたか?っていうのはサイト運営しているとちょっと気になります。 各ページの閲覧回数が分かれば、 情報が古くなってしまって、直さなきゃなぁと思っているページに沢山アクセスがあって、優先的に修正したり、 気合入れて更新しているページがあんまり開かれていなくて、そのページへのリンクの仕方を 検討し直したり、そんなようなことができます。

研究のポイント

各ページのアクセス数を知りたいっていうと、 ページ毎にアクセスカウンターを付けるという方法が 思いつきますが、それはちょっと面倒だし大変ですよね。 そこで、1つのCGIプログラムで各ページの閲覧回数をカウントしちゃおうというのが今回の研究課題です。

結果

リファラーを利用します

リファラーっていうものがありましたね。 リファラーというのは、そのCGIプログラムにリンクしていたページのURLのことでした。 これを使って、1つのCGIプログラムでページ毎のカウントを行うことができそうです。 つまり、CGIプログラムの呼び出し元URL毎にカウンターの値を保持、処理するようなCGIプログラムを作ります。

作る関数の仕様

今回はURL毎にカウントを行いますが、URLというのは結局のところ文字列です。 ですからURLにこだわる必要はなくて、文字列ならなんでもいいわけです。 ということで、作るプログラムが持つべき機能は、次のようなものになります。

(1) 文字列毎にカウントを保持していて、特定の文字列を指定してカウントを増やすことができる
(2) その情報をファイルに保存、ファイルから読み込むことができる

この2つの他にも、重複カウントの防止機能とかが付いている方がいいのですが、 それは後回しにしましょう。

いつものように、後で別のCGIプログラムにも応用できるように、関数にします。 作る関数の引数などは次のようにしましょう。

カウント増加関数(ファイル名, カウントを上げる対象文字列)

関数名が悩むところですが、次のようにしました。てきとうです。

incl_counters(ファイル名, カウントを上げる対象文字列)
カウントを増やす incl_counters 関数

文字列毎にカウントを保持するといえば、毎度のことですが連想配列が利用できますね。 ホント、お世話になります連想配列には。 そして、連想配列をファイルに書き込む、ファイルから読み込むっていう関数は 以前作っていますので、それが利用できます。 ファイルの書き込みをするときにはファイルロックが必須ですが、 それも以前作ってありますね。…となると、あんまりやることがないかも?

作成したCGIプログラム

pvcounter.cgi
#!/usr/bin/perl

require 'counters.pl';

$fname = 'pvcounter.txt';
$ref   = $ENV{'HTTP_REFERER'};

if ($ref ne "") {
	plab::incl_counters($fname, $ref);
}

print "Content-Type: text/html\n\n";
counters.pl
package plab;

require 'hashfile.pl';
require 'lock.pl';

# 引数(ファイル名, カウントを上げるキー)
# 戻値(カウント)
sub incl_counters
{
	local $fname   = $_[0];
	local $key     = $_[1];
	local $lockdir = "incl.lockdir";

	plab::lock($lockdir);
		%counters = plab::readhashfile($fname);
		++$counters{$key};
		plab::writehashfile($fname, %counters);
	plab::unlock($lockdir);

	return $counters[$key];
}

1;

実行結果

今回作った pvcounter.cgi は IFRAME タグを使って次のようにウェブページに仕込みます。 何も表示などしないので、サイズは1x1で最小にしています。

<iframe src=pvcounter.cgi width=1 height=1 frameborder=0></iframe>

このページでも、ここにカウンターを仕込んでます(見えません) →

他にも、pvcounter.cgi を仕込んだページをいくつか作りました。 それぞれ、クリックするとそのページの閲覧回数が1増えます。

pvcounter.cgiを仕込んだページ その1
pvcounter.cgiを仕込んだページ その2
pvcounter.cgiを仕込んだページ その3
pvcounter.cgiを仕込んだページ その4
pvcounter.cgiを仕込んだページ その5

現在の各ページの閲覧回数はこちらのファイルに保存されています。

現在の閲覧回数(データファイルそのまま)

考察

動きました

今まで作成したライブラリ関数が役にたって、簡単に目的のCGIプログラムを作ることができました。 役に立ちそうなものをライブラリ関数にしておくっていうのがいかに大事かわかる瞬間ですね。

今回はカウントするところまで。次はカウントした結果を画面に表示する関数が欲しいですね。 生のデータファイルを見ても、みにくいしつまらないですから。 それに、閲覧回数の多い順で表示するっていうことはやっぱりしたいです。 ウェブページ人気ランキングですね。

あと、今回作ったCGIプログラムは何も表示しないですが、 作成した incl_counters 関数は戻り値としてカウントの値を返しますので、 これを画面に表示するようにすれば、各ページの閲覧回数をカウントする アクセスカウンターとして機能させることができます。 でも、重複カウントの処理をしていないので現状ではそういう使い方には向かないかも知れません。

リファラーってすごいです

ページアンケートの研究でもリファラーを使いましたが、 今回もリファラーが大活躍です。便利なものですね、リファラーって!

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

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