このページの公開には事前にfutomiさんに許可を頂いています。
このページはVer3.7の時に書いたやつですが、行数が多少変わったもののVer3.81でも同じように改造できるようです。
ていうか、僕自身が自分用にけっこうちょこちょこ改造しているので行番号はあまりあてになりません(爆)
参考程度にしておいてください
※この「futomi's CGI Cafe 高機能アクセス解析CGI(以下:acc)」だけではなく、他のCGIに Jcode.pm を実装する場合でも同じような方法でできると思います。
既存の Jcode.pl の替わりに Jcode.pm を使用することによって、googleなどの検索ワードをちゃんと表示できるようにする。(実装例)
以下のファイルをダウンロードしてください
ダウンロードしたファイルを解凍します。この中で必要なのは「Jcode.pm」と「Jcodeディレクトリ」です。これらをacc.cgiがある場所に転送します(アスキーモードでもバイナリモードでもどちらでもかまいません)
他のCGIなどで Jcode.pm を使用している、または使用する可能性がある場合は別のディレクトリに設置することも可能です。その場合の設置例は以下のようにしてください。
|
この場合、acc.cgiの1行目の「#!/usr/local/bin/perl」を「#!/usr/local/bin/perl -I../lib」に書き換えてください。(acclog.cgiの方は必要ありません)
改造点はだいたい以下の通りです。
1.14〜16行目
jcode.pl が存在しないとエラーを返す部分を、削除orコメントアウト(行頭に「#」を挿入)する。
改 造 前 |
unless(-e './jcode.pl') { &ErrorPrint('jcode.plがありません。'); } |
---|---|
改 造 後 |
#unless(-e './jcode.pl') { # &ErrorPrint('jcode.plがありません。'); #} |
2.24行目
jcode.pl を読み込もうとしている箇所を、Jcode.pm を読み込ませるようにする。
改 造 前 |
require './jcode.pl'; |
---|---|
改 造 後 |
use Jcode; |
3.465行目、1665行目etc
jcode.pl の関数を全部 Jcode.pm の関数に書き換える
acc.cgi 中の「&jcode::」となっている箇所を全部「&Jcode::」に書き換えてください。秀丸などのテキストエディタなどの全置換機能を利用する場合は「大文字・小文字の区別」「単語ごとに検索」辺りにチェックを入れてください。(手作業で1つ1つ書き換えていくとどこかでミスをするかもしれないので、なるべくエディタの全置換機能を利用した方がいいです^^;)
accではリンク元URLが存在しない場合は表示されないが、「リンク元URLが存在しない場合」=「ブックマークorURL直接入力によるアクセス」と仮定することによって表示させるようにする。(実装例)
以下のファイルをダウンロードしてください
改造点はだいたい以下の通りです。
1.13行目(上の方であれば何行目でも構いません)
ブックマークとして表示する文字列(以下:ブックマーク文字列)の設定をする
改 造 前 |
|
---|---|
改 造 後 |
#-------------------------------------------------------------------- #リンク元URL一覧で「ブックマーク」として表示する文字列(HTMLタグ可) #-------------------------------------------------------------------- $BOOKMARK = '<b>[ ブックマーク or URL直接入力 ]</b>'; |
2.400〜401行目
リファが存在しない場合にブックマークとしてカウントさせる
改 造 前 |
next unless($referer{$key} =~ /^http/); $referer_list{$referer{$key}} ++; |
---|---|
改 造 後 |
# 念のためにコメントアウトだけして残しておきます #next unless($referer{$key} =~ /^http/); #$referer_list{$referer{$key}} ++; if($referer{$key} eq '-'){ $referer_list{$BOOKMARK} ++; } else{ next unless($referer{$key} =~ /^http/); $referer_list{$referer{$key}} ++; } |
3.1117行目
「リンク元サイト」のカウントの部分で、ブックマーク文字列が来た時は除外させる
改 造 前 |
if($Flag) {next;} |
---|---|
改 造 後 |
if($url eq $BOOKMARK){ $Flag = 1; } if($Flag) {next;} |
※acc.cgi では自サイトからのリンクを「リンク元解析対象外URL」として設定することができますが、ブックマーク文字列を強引に「リンク元解析対象外URL」と認識させてforループから強引に抜けさせてます。まぁ、accconfig.cgi の@MY_SITE_URLs に入れることも出来ましたが、それだとブックマーク文字列を @MY_SITE_URLs よりも前に定義しないといけなさげだし、スマートじゃ無かったので(^^;
4.1190行目
ブックマーク文字列を表示する場合は半角50文字の表示制限をとっぱらう
改 造 前 |
print "<TR BGCOLOR=\"#EAEAEA\"><TD ALIGN=\"CENTER\">$dsp_order</TD><TD><A HREF=\"$key\">$dsp_url</A></TD><TD ALIGN=\"RIGHT\">$referer_list{$key}</TD><TD class=\"size2\">\n"; |
---|---|
改 造 後 |
# 念のためにコメントアウトだけして残しておく #print "<TR BGCOLOR=\"#EAEAEA\"><TD ALIGN=\"CENTER\">$dsp_order</TD><TD><A HREF=\"$key\">$dsp_url</A></TD><TD ALIGN=\"RIGHT\">$referer_list{$key}</TD><TD class=\"size2\">\n"; # URLリファが見つからない場合は、ブックマーク or URL直接入力 if($key eq $BOOKMARK){ print "<TR BGCOLOR=\"#EAEAEA\"><TD ALIGN=\"CENTER\">$dsp_order</TD><TD>$key</TD><TD ALIGN=\"RIGHT\">$referer_list{$key}</TD><TD class=\"size2\">\n"; } else{ print "<TR BGCOLOR=\"#EAEAEA\"><TD ALIGN=\"CENTER\">$dsp_order</TD><TD><A HREF=\"$key\" title=\"$key\">$dsp_url</A></TD><TD ALIGN=\"RIGHT\">$referer_list{$key}</TD><TD class=\"size2\">\n"; } |
注1)この改造は、「1.Jcode.pmを実装する」と「2.ブックマークやURL直接入力時のアクセスも表示可能にする」を実行し、CGIが問題なく動作することを確認してから行ってください。
通常googleなどの検索エンジンで検索をかけた時のURLは
のようになっていますが、それを
http://www.google.co.jp/search?q=修猷館 脇山口連合 飯塚支部&ie=UTF-8&oe=UTF-8&hl=ja&lr=
という風にデコードしてやることでアクセス結果の表示を分かりやすくすることができます(実装例)
注2)OSやブラウザなどの環境や、はたまた検索エンジンによってはデコードした後のURLが正常にリンクできない場合があるようです(パラメータをそのままShift-JISで処理しているスクリプトなら大丈夫みたいです)。その場合の保険として、デコード前のURLを[・]で残しておきます。
改造点はだいたい以下の通りです。
1.1180行目近辺(PrintRefererUrl内)
改造箇所が少しややこしいので、以下を参考に書き換えてください。改造箇所は赤字のところ。PrintRefererUrlをそのまま上書きしてやるのが一番てっとり早いと思いますが。
sub PrintRefererUrl { # リンク元URL print "<HR>\n"; print '<A NAME="LINK_URL"><B class="size4">リンク元URLレポート</B></A>',"\n"; print '<font class="size4">(リンク先URLが開けない場合は <font size=1>[・]</font> を開いてみてください)</font>',"\n"; print '<TABLE BORDER="0">',"\n"; print '<TR BGCOLOR="#3A6EA5"><TH CLASS=ListHeader><FONT COLOR="#FFFFFF">順位</FONT></TH><TH CLASS=ListHeader><FONT COLOR="#FFFFFF">URL</FONT></TH><TH CLASS=ListHeader><FONT COLOR="#FFFFFF">リクエスト数</FONT></TH><TH CLASS=ListHeader><FONT COLOR="#FFFFFF">グラフ</FONT></TH></TR>',"\n"; my($key, $dsp_url, $ExceptUrl, $Flag); my($order) = 1; my($dsp_order) = 1; foreach $key (ValueSort(\%referer_list)) { $key2 = &URL_Decode($key); # デコードした後のURL &Jcode::convert(\$key2, "sjis"); $Flag = 0; if(scalar @MY_SITE_URLs) { for $ExceptUrl (@MY_SITE_URLs) { if($key =~ /^$ExceptUrl/) { $Flag = 1; last; } } } if($Flag) {next;} unless($referer_list{$key} == $pre_velue) { $dsp_order = $order; last if($dsp_order > $ROW); } $rate = int($referer_list{$key} * 10000 / $loglines) / 100; $GraphLength = int($GRAPHMAXLENGTH * $rate / 100); # 表示するURLを、50文字に縮める if(length($key2) > 50) { $dsp_url = substr($key2, 0, 50); $dsp_url .= '...'; } else { $dsp_url = $key2; } #print "<TR BGCOLOR=\"#EAEAEA\"><TD ALIGN=\"CENTER\">$dsp_order</TD><TD><A HREF=\"$key\">$dsp_url</A></TD><TD ALIGN=\"RIGHT\">$referer_list{$key}</TD><TD class=\"size2\">\n"; # URLリファが見つからない場合は、ブックマーク or URL直接入力 if($key2 eq $BOOKMARK){ print "<TR BGCOLOR=\"#EAEAEA\"><TD ALIGN=\"CENTER\">$dsp_order</TD><TD>$key</TD><TD ALIGN=\"RIGHT\">$referer_list{$key}</TD><TD class=\"size2\">\n"; } else{ print "<TR BGCOLOR=\"#EAEAEA\"><TD ALIGN=\"CENTER\">$dsp_order</TD><TD><A HREF=\"$key2\" title=\"$key2\">$dsp_url</A> <font size=1>[<a href=\"$key\" title=\"$key\">・</a>]</font></TD><TD ALIGN=\"RIGHT\">$referer_list{$key}</TD><TD class=\"size2\">\n"; } if($rate < 1) { print ""; } else { print "<IMG SRC=\"$IMAGE_URL/graphbar\.gif\" WIDTH=\"$GraphLength\" HEIGHT=\"10\">"; } print " ($rate%)</TD></TR>\n"; $pre_velue = $referer_list{$key}; $order ++; } print "</TABLE>\n"; print "<br><br>\n"; } |
「リクエストレポート」でもこれと同じ要領でできると思います。
「リンク元URLレポート」はどのページのリンクからアクセス解析対象ページにとんできたのかのレポートですが、googleやyahooなどの検索エンジンからのリンクが増えるととても見づらいものになります。検索キーワード自体は「検索エンジンの検索キーワードリスト」で閲覧可能なのでリンク元URLレポートの方はある程度一括化していいかもしれません。そこで、URLの置換機能を実装してみることにします。(実装例)
※ひょっとしたら前項でやったことの意味が無くなるかもしれません(ぇー
accconfig.cgi に置換URLのリストを追加します。accconfig.cgi に以下を追加してください。置換URLの記述形式についても以下のコメント参照。
#-------------------------------------------------------------------- #■URLの置換設定 # '置換元のURL', '置換後のURL', '表示する文字列(タイトル)', … # の書式にしてください。 # 例: @MY_CONVERT_URLs = ('http://www.google.co.jp/search?', 'http://www.google.co.jp/', '【検索エンジン】google(jp)', …); # Perlの仕様上文字列中でなければどこでも改行できるので、 # 下のように3つごとに区切るのが一番見やすいと思われます(^^; # # また、置換後のURLに 'http://www.hoge.com' を指定すると、 # 'http://www.hoge.com/index.html' と 'http://www.hoge.com/hoge/' # の両方が置換対象となります。 # # 2つ以上の置換元URLに対し同じ置換後URLを使用すれば1つにまとめることが # できますが、「表示タイトル」が統一されていない場合どちらが採用されるかは # 不明です。なるべく統一させておいてください。 #-------------------------------------------------------------------- # 一通りの検索エンジンリスト(自分のHPのアクセス解析のログを参考に。だいたいこれだけあれば困る事はないハズ) @MY_CONVERT_URLs = ( 'http://www.google.co.jp' , 'http://www.google.co.jp/' , '【検索エンジン】Google(jp)', 'http://images.google.co.jp' , 'http://www.google.co.jp/' , '【検索エンジン】Google(jp)', 'http://66.102.7.104' , 'http://www.google.co.jp/' , '【検索エンジン】Google(jp)', 'http://www.google.com' , 'http://www.google.com/' , '【検索エンジン】Google(com)', 'http://images.google.com' , 'http://www.google.com/' , '【検索エンジン】Google(com)', 'http://216.239.53.104' , 'http://www.google.com/' , '【検索エンジン】Google(com)', 'http://216.239.57.104' , 'http://www.google.com/' , '【検索エンジン】Google(com)', 'http://www.google.com.tw' , 'http://www.google.com.tw/', '【検索エンジン】Google(tw)', 'http://images.google.com.tw', 'http://www.google.com.tw/', '【検索エンジン】Google(tw)', 'http://www.google.fr' , 'http://www.google.fr/' , '【検索エンジン】Google(fr)', 'http://images.google.fr' , 'http://www.google.fr/' , '【検索エンジン】Google(fr)', 'http://search.yahoo.co.jp/bin/query?', 'http://www.yahoo.co.jp/', '【検索エンジン】Yahoo!(jp)', 'http://cache.yahoofs.jp/cache?' , 'http://www.yahoo.co.jp/', '【検索エンジン】Yahoo!(jp)', 'http://www.excite.co.jp/search.gw?' , 'http://www.excite.co.jp/', '【検索エンジン】excite(jp)', 'http://home.excite.co.jp/search.gw?', 'http://www.excite.co.jp/', '【検索エンジン】excite(jp)', 'http://so-net.excite.co.jp/search.gw?', 'http://www.excite.co.jp/', '【検索エンジン】excite(jp)', 'http://hi-ho.excite.co.jp/search.gw?', 'http://www.excite.co.jp/', '【検索エンジン】excite(jp)', 'http://search.msn.co.jp/', 'http://www.msn.co.jp/', '【検索エンジン】MSN(jp)', 'http://cgi.search.biglobe.ne.jp/cgi-bin/search', 'http://www.biglobe.ne.jp', ' 【検索エンジン】BIGLOBEサーチ attayo', 'http://www.infoseek.co.jp/OTitles?', 'http://www.infoseek.co.jp/', '【検索エンジン】infoseek', 'http://search.fresheye.com/?', 'http://www.fresheye.com/', '【検索エンジン】フレッシュアイ', 'http://search.goo.ne.jp/web.jsp?', 'http://www.goo.ne.jp/', '【検索エンジン】goo', 'http://search.nifty.com/cgi-bin/search.cgi?', 'http://www.nifty.com/', '【検索エンジン】Nifty', 'http://dion.excite.co.jp/search.gw?', 'http://www.dion.ne.jp/', '【検索エンジン】DION Search', 'http://websearch.naver.co.jp', 'http://www.naver.co.jp/', '【検索エンジン】NAVER', 'http://ocnsearch.goo.ne.jp/ocn.jsp?', 'http://www.ocn.ne.jp/', '【検索エンジン】OCNサーチ', # '', '', '【検索エンジン】', ); |
1.1265行目近辺(PrintRefererUrl内)
改造箇所は赤字のところ。PrintRefererUrlをそのまま上書きしてやるのが一番てっとり早いと思います。前項の改造を施している方はそちらも再度書き換えてください。
sub PrintRefererUrl { # リンク元URL print "<HR>\n"; print '<A NAME="LINK_URL"><B class="size4">リンク元URLレポート</B></A>',"\n"; print '<font class="size4">(リンク先URLが開けない場合は <font size=1>[・]</font> を開いてみてください)</font>',"\n"; print '<TABLE BORDER="0">',"\n"; print '<TR BGCOLOR="#3A6EA5"><TH CLASS=ListHeader><FONT COLOR="#FFFFFF">順位</FONT></TH><TH CLASS=ListHeader><FONT COLOR="#FFFFFF">URL</FONT></TH><TH CLASS=ListHeader><FONT COLOR="#FFFFFF">リクエスト数</FONT></TH><TH CLASS=ListHeader><FONT COLOR="#FFFFFF">グラフ</FONT></TH></TR>',"\n"; my($key, $dsp_url, $ExceptUrl, $Flag); my($order) = 1; my($dsp_order) = 1; # URLを置換。以下、referer_listではなくreferer_list2を使用します。 for $key (keys %referer_list) { $key2 = $key; $Flag = 0; if(scalar @MY_CONVERT_URLs) { for($i=0; $i<@MY_CONVERT_URLs; $i+=3){ $ExceptUrl = $MY_CONVERT_URLs[$i]; # 置換元のURL $AfterUrl = $MY_CONVERT_URLs[$i+1]; # 置換後のURL $Title = $MY_CONVERT_URLs[$i+2]; # 表示するタイトル if($key =~ /^$ExceptUrl/) { $key2 = $AfterUrl; $Flag = 1; $referer_list2_title{$key2} = $Title;#表示用のタイトル(置換後のURLを入れればタイトルが返ってくるという寸法) last; } } } $referer_list2{$key2} += $referer_list{$key}; $referer_list2_flag{$key2} = $Flag; # URL置換をしたかどうかのフラグ } foreach $key (ValueSort(\%referer_list2)) { $Flag = 0; if(scalar @MY_SITE_URLs) { for $ExceptUrl (@MY_SITE_URLs) { if($key =~ /^$ExceptUrl/) { $Flag = 1; last; } } } if($Flag) {next;} unless($referer_list2{$key} == $pre_velue) { $dsp_order = $order; last if($dsp_order > $ROW); } $rate = int($referer_list2{$key} * 10000 / $loglines) / 100; $GraphLength = int($GRAPHMAXLENGTH * $rate / 100); # 表示するURLを、50文字に縮める if(length($key) > 50) { $dsp_url = substr($key, 0, 50); $dsp_url .= '...'; } else { $dsp_url = $key; } # print "<TR BGCOLOR=\"#EAEAEA\"><TD ALIGN=\"CENTER\">$dsp_order</TD><TD><A HREF=\"$key\">$dsp_url</A></TD><TD ALIGN=\"RIGHT\">$referer_list{$key}</TD><TD class=\"size2\">\n"; # URLリファが見つからない場合は、ブックマーク or URL直接入力 if($key eq $BOOKMARK){ print "<TR BGCOLOR=\"#EAEAEA\"><TD ALIGN=\"CENTER\">$dsp_order</TD><TD>$key</TD><TD ALIGN=\"RIGHT\">$referer_list2{$key}</TD><TD class=\"size2\">\n"; } elsif($referer_list2_flag{$key}==1){ print "<TR BGCOLOR=\"#EAEAEA\"><TD ALIGN=\"CENTER\">$dsp_order</TD><TD><A HREF=\"$key\" title=\"$key\"><b>$referer_list2_title{$key}</b></A></TD><TD ALIGN=\"RIGHT\">$referer_list2{$key}</TD><TD class=\"size2\">\n"; } else{ print "<TR BGCOLOR=\"#EAEAEA\"><TD ALIGN=\"CENTER\">$dsp_order</TD><TD><A HREF=\"$key\" title=\"$key\">$dsp_url</A></TD><TD ALIGN=\"RIGHT\">$referer_list2{$key}</TD><TD class=\"size2\">\n"; } if($rate < 1) { print ""; } else { print "<IMG SRC=\"$IMAGE_URL/graphbar\.gif\" WIDTH=\"$GraphLength\" HEIGHT=\"10\">"; } print " ($rate%)</TD></TR>\n"; $pre_velue = $referer_list2{$key}; $order ++; } print "</TABLE>\n"; print "<br><br>\n"; } |
acc Ver3.81で文字化けが解消されたので削除しました。
accではデフォルトではログファイルが300KBごとにローテーションされるようになっていますが、過去ログを保存するようにしていくとサーバ容量を圧迫するようになってしまいます。そこで、過去ログをgzipで圧縮しようと思います。だいたい1/8くらいになります。
注)gzipで圧縮するためには、あらかじめお使いのサーバでgzip圧縮・展開をサポートしているか調べる必要があります。とりあえず既存の過去ログを一括してgzip圧縮するcgiを作ってみたのでご利用ください。(こちらからダウンロード)
もしこれでちゃんと圧縮されたならgzipをサポートしていると考えていいと思います。もし圧縮されなかったら諦めてください(^^;
accconfig.cgiのどこにでもいいので、以下を追加してください。
#-------------------------------------------------------------------- #■gzip圧縮を使うかどうか # 使うなら「1」、使わないなら「0」 #-------------------------------------------------------------------- $USE_GZIP = 1; #-------------------------------------------------------------------- #■gzipプログラムの場所 # もしこれで動かない場合はお使いのサーバに問い合わせるか # which gzipとかで探してください #-------------------------------------------------------------------- $GZIP = '/bin/gzip'; |
1.333行目近辺(LogLotation内)
改 造 前 |
sub LogLotation { (中略) if($LOTATION == 1) { if($log_size > $LOTATION_SIZE) { if($LOTATION_SAVE) { rename("$LOG", "$LOG\.$DateStr\.cgi"); } else { unlink("$LOG"); } } } elsif($LOTATION == 2 || $LOTATION == 3) { (中略) } |
---|---|
改 造 後 |
sub LogLotation { (中略) if($LOTATION == 1) { if($log_size > $LOTATION_SIZE) { if($LOTATION_SAVE) { rename("$LOG", "$LOG\.$DateStr\.cgi"); if($USE_GZIP) { system($GZIP, "$LOG\.$DateStr\.cgi"); } } else { unlink("$LOG"); } } } elsif($LOTATION == 2 || $LOTATION == 3) { (中略) } |
1.30行目近辺
改 造 前 |
use CGI; |
---|---|
改 造 後 |
use CGI; use File::Copy; |
2.97行目近辺
改 造 前 |
# ログファイルを読み取る if(-e $SelectedLogFile) { open(LOGFILE, "$SelectedLogFile") || &ErrorPrint("アクセスログ「$SelectedLogFile」をオープンできませんでした"); } else { &ErrorPrint("アクセスログ($SelectedLogFile)がありません。"); } (中略) close(LOGFILE); my $loglines = $i; (中略) # ログファイルのサイズを調べる(バイト) my $log_size = &AnalyzeLogfileSize($SelectedLogFile); |
---|---|
改 造 後 |
# もしgzip圧縮されていたら展開する my $temp = ''; my $gzip_size = 0; my $temp_size = 0; if($USE_GZIP && $SelectedLogFile =~ /.cgi.gz$/) { $gzip_size = &AnalyzeLogfileSize($SelectedLogFile); # コピーを作っておかないと過去ログがどんどん消えていってしまう(汗 copy($SelectedLogFile, "$SelectedLogFile.bak"); system($GZIP, "-d", $SelectedLogFile); move("$SelectedLogFile.bak", "$SelectedLogFile"); $temp = $SelectedLogFile; $temp =~ s/.gz$//i; $temp_size = &AnalyzeLogfileSize($temp); if(-e $temp) { open(LOGFILE, "$temp") || &ErrorPrint("過去ログファイル「$temp」をオープンできませんでした"); } # ログファイルを読み取る } elsif(-e $SelectedLogFile) { open(LOGFILE, "$SelectedLogFile") || &ErrorPrint("アクセスログ「$SelectedLogFile」をオープンできませんでした"); } else { &ErrorPrint("アクセスログ($SelectedLogFile)がありません。"); } (中略) close(LOGFILE); # GZIP用に展開したログの後始末 if($USE_GZIP && $temp ne ''){ unlink("$temp"); } my $loglines = $i; # ログファイルのサイズを調べる(バイト) my $log_size; if($USE_GZIP && $temp ne ''){ $log_size = $temp_size; } else{ $log_size = &AnalyzeLogfileSize($SelectedLogFile); } |
PSP(PlayStation Portable)のUserAgent(Mozilla/4.0 (PSP (PlayStation Portable); 2.00))をaccで識別できるようにしてみます。
下記を参考に各自書き換えてみてください(赤字の部分が追加する箇所です)
acc.cgiの1974行目近辺
sub User_Agent { my($user_agent, $remote_host) = @_; my($platform, @agentPart, $browser, $browser_v); my($platform_v, @agentPart2, $user_agent2, @buff, @buff2, @buff3); my($flag, $key, @version_buff); if($user_agent =~ /DoCoMo/i) { (中略) } elsif($user_agent =~ /^Mozilla\/([0-9\.]+)/) { $browser = 'NetscapeNavigator'; $browser_v = $1; if($user_agent =~ /Gecko\//) { if($user_agent =~ /Netscape[0-9]*\/([0-9a-zA-Z\.]+)/) { $browser_v = $1; } elsif($user_agent =~ /(Phoenix|Chimera|Firefox|Camino)\/([0-9a-zA-Z\.]+)/) { $browser = $1; $browser_v = $2; } else { $browser = 'Mozilla'; if($user_agent =~ /rv:([0-9\.]+)/) { $browser_v = $1; } else { $browser_v = ''; } } } if($user_agent =~ /Win95/) { $platform = 'Windows'; $platform_v = '95'; } elsif($user_agent =~ /PSP \(PlayStation Portable\)/i) { $platform = 'PlayStation Portable'; if($user_agent =~ /PSP \(PlayStation Portable\);\s+([a-zA-Z0-9\.]+)/i) { $platform_v = $1; } else { $platform_v = ''; } } elsif($user_agent =~ /Windows 95/) { $platform = 'Windows'; $platform_v = '95'; |