【簡単カウンターCGI】Perlでアクセスカウンターを簡単につくってみよう


PC/プログラム/ゲーム/ネット系レポ TOPはこちら

Perlを使って、アクセスカウンターを簡単に作ってみる

ここでは、ページごとのアクセスカウンターを簡単につくることができるスクリプトをご紹介します。

(1)アクセスカウンターPerl (CGI)プログラム 本体

このアクセスカウンタの特徴は、

・アクセス回数を数字で表示(HTMLページとして表示するので、iframe をつかってカウンタを埋め込みます)

・CGIのGETメソッドでカウンタのファイル名を任意に指定できる

・日付毎のトータルカウントも同時にカウント(表示はしない)

です。カウンタのファイル名を任意に指定できるので、ページのURLをカウンタ名として引き渡せば、各ページごとに異なるカウンタを表示できます。また、特定のキーワードを引き渡せば、同じキーワードが引き渡されたページの合計カウンタを表示できます。

また、日付毎のトータルカウントは、TOTAL_日付.txt(例えば、TOTAL_20180909.txt という形式)のファイルでカウント数を保存します。

 

以下がカウンターのプログラムです。超簡単です。

/cgi/count/count.cgi (プログラムなので、属性は、実行可能な属性 705 などに変更しておく必要があります)

#!/usr/bin/perl 
# アクセスカウンタ
print "Content-type: text/html; charset=Shift_JIS\n\n";

#カウンタを保存するファイル名を、GETメソッドの QUERY_STRING から受け取る
$filename = $ENV{'QUERY_STRING'};
$filename = substr($filename, 0, 128); # 変なコードが入れられないように128文字でカットしておく

#カウントファイルから読み込み
#ファイル名に へんな文字列がぶっこまれないようにする場合
#例えば [ABC] から始まるファイル名に限定することで、意図しない文字列を入れたCGI実行を防ぐ。
#そのようなフィルタルールを行う場合は、以下の行の 注釈 # を外す。
# if ( substr($filename, 0 , 3) ne '[ABC]' ) { exit(0); }  #[ABC] から始まらない場合、さようなら

if ($filename eq '') { $filename="temp"; }

$count = -1;
$filename_temp = "temp_" . $filename;

open IN, "$filename";
$count = <IN>;
close(IN);

# カウント増加
$count++;

# カウントファイルに書き込み
open(OUT, ">$filename_temp" );
print OUT $count;
close(OUT);

#ファイルリネーム
rename $filename_temp, $filename;

#表示
print "<html><body topmargin=\"0\" leftmargin=\"0\">$count</body></html>";

################################################
####以下は、日にち別の累計を記録。 ファイル名は TOTAL_20180918.txt などの形式
################################################

my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);

$year = $year + 1900;
$mon = $mon + 1;

$filename = sprintf("TOTAL_%04d%02d%02d.txt", $year, $mon, $mday );
$filename_temp = "temp_" . $filename;

$count=-1;

#累計を記載したファイル
open IN, "$filename" ;
$count = <IN>;
close(IN);

# カウント増加
$count++;

# カウントファイルに書き込み
open(OUT, ">$filename_temp" );
print OUT $count;
close(OUT);

#ファイルリネーム
rename $filename_temp, $filename;

exit(0);

処理の中でカウンターファイルをリネームしていますが、これはいろいろ試した結果、カウンタをtempファイルに書き込んだ後、リネームするやり方が、アクセス競合時でもデッドロックしにくいからです。ベストではないですが実績が良かったので採用しています。

(2)カウンターCGIの呼び出しHTML

HTMLからiframeで呼び出すと、iframeの中にカウンターが表示されます。

ホームページなどのHTMLファイルには以下のように記載して、呼び出します。

※例では、CGIのプログラムが、 /cgi/count/count.cgi の場合です。

AAA.html
〜ホームページの本文〜

<iframe src="/cgi/count.cgi?pege1" width="80px" height="24px" frameborder="0"></iframe>

〜ホームページの本文〜

表示させたいところに、上のコードを入れます。iframeで埋め込みます。サイズは適宜調整してください。

なお、「page1」と赤字で書いてますが、これがカウンター数を保存するファイル名となります。

ページごとにカウンタを作る場合は、それぞれ page1 に相当するところを異なる文字列にします。

◆自動的にページ毎のカウンタを作りたい場合

ファイル名別のアクセスカウンタにしたい場合は、各ページに以下のようなJavascriptを書いておくと、ファイル名がURLになるので、いちいち記載しなくても良いです。共通的な関数部分は JSファイルにしておいて読み込ませれば、各HTMLファイルに以下の関数を記載する手間も省けます。

注意点は、URLをwindow.location.href; で取得して、その文字列を使用するとページごとにカウンタファイルがユニークになるのですが、URLにはファイル名に使わない方が良い文字列が含まれる場合が多いので、それらを _ に置き換えておくことが必要です。

 

BBB.html
<HEAD>
<SCRIPT> 
function view_counter()
{
var url = window.location.href;
var url_rep = "";

// :  など、あまりファイル名に適さない文字列はすべて _ に置き換えてしまう。
url_rep = url.replace( /\//g , "_" ) ;
url_rep = url_rep.replace( /\:/g , "_" ) ;
url_rep = url_rep.replace( /\./g , "_" ) ;
url_rep = url_rep.replace( /\?/g , "_" ) ;
url_rep = url_rep.replace( /\\/g , "_" ) ;

document.write ('<iframe src="/cgi/count/count.cgi?');
document.write ( url_rep );
document.write ('" width="80px" height="24px" frameborder="0"></iframe>');
}

</SCRIPT> 
</HEAD>

<BODY>

〜ホームページの本文〜

<SCRIPT> view_counter(); /<SCRIPT> 

</BODY>

応用編

今日の総合計アクセス数を表示してみたい

ページ単位ではなく、すべてのページの本日の合計アクセス数、って気になりますね。

上に記載したカウンターPerl (CGI)プログラムは、ページごとのカウントとその表示のみで、各日の総トータルカウンタ数は記録しているものの表示はしていません。

そのため、別途、その日の総トータルのアクセス数の表示のみ行うプログラムが以下となります。なお、このCGIは、その日の総トータルのカウンタ数の表示のみで、カウントする動作はしません。

 

/cgi/count/viewtotal.cgi (プログラムなので、属性は、実行可能な属性 705 などに変更しておく必要があります)

#!/usr/bin/perl 
# アクセスカウンタ

print "Content-type: text/html; charset=Shift_JIS\n\n";

$count = 0;

#累計を記載したファイル
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);

$year = $year + 1900;
$mon = $mon + 1;

$filename = sprintf("TOTAL_%04d%02d%02d.txt", $year, $mon, $mday );

open IN, "$filename";
$count = <IN>;
close(IN);

#表示
print "<html><body topmargin=\"0\" leftmargin=\"0\">$count</body></html>";

exit(0);

 

CCC.html
〜ホームページの本文〜

<iframe src="/cgi/viewtotal.cgi" width="80px" height="24px" frameborder="0"></iframe>

〜ホームページの本文〜

表示は、iframeで埋め込みます。サイズは適宜調整してください。

今月・先月の総合計アクセス数を一覧で表示してみたい

今度は、今月と先月の総合計アクセス数を一覧形式で表示します。

/cgi/count/viewtotalmonth.cgi(プログラムなので、属性は、実行可能な属性 705 などに変更しておく必要があります)

#!/usr/bin/perl 
# アクセスカウンタ

print "Content-type: text/html; charset=Shift_JIS\n\n";
$count = 0;

#今日の日付を取得
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);

$year = $year + 1900;
$mon = $mon + 1;

#表示
print "<html><body><br>";

#先月表示

$mon = $mon -1;

if ( $mon < 1 )
{ $mon = 12;
$year = $year -1;
}

print "<b>$year年$mon月</b><br><br>";

for ($i=1 ; $i<=31 ; $i++)
{
$count = "0";

$filename = sprintf("TOTAL_%04d%02d%02d.txt", $year, $mon, $i );

#ファイルを開いてエラーならば count=なし 
if (!open IN, "$filename") 
{ $count = "なし";
}
else
{ $count = <IN>;
close(IN);
}
#表示
print "$filename = $count<br>";
}

# 今月表示

$mon = $mon + 1 ;

if ( $mon > 12 )
{ $mon = 1;
$year = $year + 1;
}

print "<br><br>";
print "<b>$year年$mon月</b><br><br>";

for ($i=1 ; $i <= 31 ; $i++)
{

$filename = sprintf("TOTAL_%04d%02d%02d.txt", $year, $mon, $i );

#ファイルを開いてエラーならば count=なし 
if (!open IN, "$filename") 
{ $count = "なし";
}
else
{ $count = <IN>;
close(IN);
}

#表示
print "$filename = $count<br>";
}

#表示
print "</body></html>";
exit(0);

 

DDD.html
〜ホームページの本文〜

<a href="/cgi/count/viewtotalmonth.cgi>総合計の一覧表示はここをクリック</a>

〜ホームページの本文〜

 

(参考)JavascriptでURL内の「:」「/」「.」 の置換する方法

URLにはエスケープ文字が含まれているので、URLをファイル名にして出力する場合、扱いにくいため、

「コロン(:)」「スラッシュ(/)」「コンマ(.)」を「アンダーバー(_)」に置換する場合があります。

これは Javascript です。

function chikan1()
{
  var url = "https://hogehoge.homepagehogehoge.co.jp/aaaa/bbbb/cccc.html";
  // (現在のURLを取得する場合は、  var url = window.location.href; と記載します。)
  var url_rep = "";

  url_rep = url.replace( /\//g , "_" ) ;
  url_rep = url_rep.replace( /\:/g , "_" ) ;
  url_rep = url_rep.replace( /\./g , "_" ) ;

  document.write ( url_rep );
 }

出力例:

http___hogehoge_homepagehogehoge_co_jp_aaaa_bbbb_cccc_html

 

実際にカウンタを表示してみよう

<次ページ> 実際にカウンタを表示してみましょう