今度は、リピーターの解析を行います。
リピーターの解析は、合計アクセス数の他、日別のアクセス数もカウントします。
そして、そのデータの取り扱いも前回の%CountDataを使用します。
#!/usr/bin/perl
# カウントデータ
$DATA_COUNT = 'count.dat';
if($ENV{'REQUEST_METHOD'} eq "POST") {
read(STDIN, $query, $ENV{'CONTENT_LENGTH'});
} else {
$query = $ENV{'QUERY_STRING'};
}
@args = split(/&/, $query);
foreach $i (@args) {
($name, $val) = split(/=/, $i);
$name =~ tr/+/ /;
$name =~ s/%([0-9a-fA-F]{2})/pack('C', hex($1))/eg;
$val =~ tr/+/ /;
$val =~ s/%([0-9a-fA-F]{2})/pack('C', hex($1))/eg;
$in{$name} = $val;
}
# アクセス解析モード
&Get_Data();
# 日付取得
(undef, undef, undef, $d, $m, $y) = localtime(time);
# 年に1900を足す
$y += 1900;
# 月に1を足す
$m++;
# 日付出力形式成型
$today = sprintf("%04d/%02d/%02d", $y, $m, $d);
# もし前回アクセス者のIPと今回のIPが違うなら
if($ENV{'REMOTE_ADDR'} ne $CountData{'REMOTE_ADDR'}) {
# カウント値加算
$CountData{$today}++;
$CountData{'REMOTE_ADDR'} = $ENV{'REMOTE_ADDR'};
}
# リピーターの解析
# リピーターの合計カウント
$CountData{$ENV{'REMOTE_ADDR'}}++;
# リピーターの本日のカウント
$CountData{"${today}$ENV{'REMOTE_ADDR'}"}++;
&Set_Data();
# アクセス解析結果表示
print "Content-type: text/html\n\n";
# 日別カウント結果
foreach(sort {$b cmp $a} keys %CountData) {
# 日付形式でなければスキップ
next if($_ !~ /^[0-9]{4}\/[0-9]{2}\/[0-9]{2}$/);
print "$_ : $CountData{$_}<br>\n";
}
# リピーター解析結果表示
foreach(sort {$CountData{$b} <=> $CountData{$a}} keys %CountData) {
# IPアドレス(IPv4)形式でなければスキップ
next if($_ !~ /^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/);
print "ユーザー:$_ (TOTAL-<b>$CountData{$_}</b>)<br>\n";
foreach $c (keys %CountData) {
# リピーターの解析データでないならスキップ
next if($c !~ /([0-9]{4}\/[0-9]{2}\/[0-9]{2})$_/);
print " $1 _ $CountData{$c}<br>\n";
}
}
データの読み込み、保存の関数は変更がないため省略しました。
擬似データベース形式の%CountDataは、他のデータと同時に取り扱っても他の処理にほぼ干渉しないため、
リピーターの解析データもそこへ保管します。
今回は、必要なデータを取り出すとき、%CountDataのキーを正規表現でふるいにかけています。
正規表現で一致したものを必要データとして認識して、処理結果を表示させます。
なお、正規表現のあとに" $1, $2...." などで、正規表現でマッチした文字列を取り出す方法があります。
正規表現で "()"によってグループ化したパターン部分を左から順に"$1, $2...." へと自動で代入していきます。
リピータの解析データの出力で、日別出力部分の日付の取得はこの方法を用いています。
しかし、この方法では、日別の出力でもソートがなされていないため、バラバラになる可能性があります。
ソートを行うためには、ここで出力したキーを一旦配列へ退避させ、ソートしながら出力させます。
foreach $c (keys %CountData) {
# リピーターの解析データでないならスキップ
next if($c !~ /[0-9]{4}\/[0-9]{2}\/[0-9]{2}$_/);
push(@tmp, $c);
}
foreach $c (sort {$b cmp $a} @tmp) {
# 日付取得
$c =~ /([0-9]{4}\/[0-9]{2}\/[0-9]{2})$_/;
print " $1 _ $CountData{$c}<br>\n";
}