referer linkを自動で追加
sorry Japanese only
PAGE作成日 2005/08/28
最終更新日 2005/08/28
page size = Mbyte

こんな事をやらせました。BigDriveページの一番下

BigDriveページは、色々なページや掲示板へリンクされています。
こんな調べ方があるよ。って飛んでこられる方が多いようですが、
私のページへジャンプしてきた方は、他にどのような掲示板で議論されて
いるのかを調べるすべはありません。
解決するには情報は沢山あった方が良いに決まっています。
良くある blogのように、勝手にリンク元の表示が追加されれば良いのになぁ。

と以前より思っていました。

フリーの CGIを提供している方の hpを見ていたら、リファラーを記録するカウンターを作られている方がいました。
これを使えばリファラーの記録ができる。記録さえされれば、後は shスクリプトでどうにでもなるぞ!

って事で referer linkを自動で追加 ページです。

リファラー記録型のカウンターを作られている at worksさん、ヒントをありがとうございました。

全体像

以下のような構造でリファラー情報をページ上に表示させます

前のページ情報を java scriptで cgiへ渡すため、ページ内に java scriptの記述。
このとき、どのファイルへリファラー情報を書き込むかのファイル名情報も一緒に渡す。

CGIは、渡されたリファラー情報とファイル名情報を分離。
ファイル名へリファラーを書き込む。
書き込むときには、ソート、統計などは行わない。ただ書き込むだけ。

1日 1回、ソート、統計を取るための shスクリプトを動かす。
同一の検索語などは、まとめて xx件のような表示になるようにして、別ファイルへ保存。

ページ内に、ソート、統計を取った後の TEXTファイルを表示する CGIを動作させるためのリンクを作る。

ページ内に java scriptの記述

<script type="text/javascript">
<!--
document.write("<img src='/access/refcount.cgi?");
document.write("dir=bigdrive","&amp;");
document.write("ref=",document.referrer);
document.write("' width='1' height='1' alt=''>");
// -->
</script>
この様な java scriptを、refererの記録を取りたいページへ記述します。

ファイル書き込み CGI

java scriptを記述したページへ飛んできたときのリファラー情報を
そのまま引き継ぎファイルへ記述する CGIスクリプトです。
#! /usr/bin/perl

# CGIがエラーを出さないためのお約束
#
print "Content-type:text/plain\n\n";

# CGIが呼び出されるときの ?以降の文字列
# が入っている環境変数を代入
#
$qst = $ENV{'QUERY_STRING'};

# referer情報を分離
#
@part = split(/&ref=/, $qst, 2);
$httpref = @part[1];

# 書き込むファイル名情報を分離
#
@file1 = split(/=/ , @part[0] , 3);
$filename = "data/@file1[1]";

$ngstring ="\$";
$stringck = index $filename , $ngstring;
if ($stringck != "-1") {
exit;
}

$ngstring ="..";
$stringck = index $filename , $ngstring;
if ($stringck != "-1") {
exit;
}

# ファイルへ書き込み
#
open wfile , ">>$filename";
print wfile $httpref;
print wfile "\n";
close wfile;

exit;

これを CGIが動作するところへ保存します。
私は refcount.cgiというファイル名で保存しました。

この CGIが呼び出されると、私の設定だと /access/data/bigdrive
というファイルへ、以下のようにリファラー情報が記述されていきます。

上記の例だと以下のように bigdriveというファイルへ記録されていきます。
http://www.google.com/search?as_q=bigdrive+%E6%B3%A8%E6%84%8F&num=100&hl=ja&c2coff=1&btnG=Google+%E6%A4%9C%E7%B4%A2&as_epq=&as_oq=&as_eq=&lr=lang_ja&as_ft=i&as_filetype=&as_qdr=all&as_occt=any&as_dt=i&as_sitesearch=
http://www.google.com/search?hl=ja&lr=lang_ja&ie=UTF-8&oe=UTF-8&q=137%EF%BC%A7%EF%BC%A2%E3%81%AE%E5%A3%81&num=50
http://search.yahoo.co.jp/bin/query?p=%3D%28bigdrive*2ch%29&n=20&yuragi=0&va=bigdrive+2ch&va_vt=any&vo_vt=any&ve_vt=any&vp_vt=any
http://www.google.com/search?as_q=bigdrive+%E6%B3%A8%E6%84%8F&num=100&hl=ja&c2coff=1&btnG=Google+%E6%A4%9C%E7%B4%A2&as_epq=&as_oq=&as_eq=&lr=lang_ja&as_ft=i&as_filetype=&as_qdr=all&as_occt=any&as_dt=i&as_sitesearch=
http://www.google.com/search?as_q=bigdrive+%E6%B3%A8%E6%84%8F&num=100&hl=ja&c2coff=1&btnG=Google+%E6%A4%9C%E7%B4%A2&as_epq=&as_oq=&as_eq=&lr=lang_ja&as_ft=i&as_filetype=&as_qdr=all&as_occt=any&as_dt=i&as_sitesearch=

http://www.google.com/search?as_q=bigdrive+%E6%B3%A8%E6%84%8F&num=100&hl=ja&c2coff=1&btnG=Google+%E6%A4%9C%E7%B4%A2&as_epq=&as_oq=&as_eq=&lr=lang_ja&as_ft=i&as_filetype=&as_qdr=all&as_occt=any&as_dt=i&as_sitesearch=

http://www.google.com/search?as_q=bigdrive+%E6%B3%A8%E6%84%8F&num=100&hl=ja&c2coff=1&btnG=Google+%E6%A4%9C%E7%B4%A2&as_epq=&as_oq=&as_eq=&lr=lang_ja&as_ft=i&as_filetype=&as_qdr=all&as_occt=any&as_dt=i&as_sitesearch=
http://search.yahoo.co.jp/bin/query?p=Bigdrive&fr=top
http://www.google.co.jp/search?client=firefox-a&rls=org.mozilla%3Aja-JP%3Aofficial_s&hl=ja&q=BIGDRIVE+%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%83%88&lr=&btnG=Google+%E6%A4%9C%E7%B4%A2
http://search.yahoo.co.jp/bin/query?p=137G%a4%ce%ca%c9&fr=top

ソート、統計するための shスクリプト

CGIでも出来るんだろうけどなぁ。

ページ呼び出すたびにソート、統計する必要も無いだろうし、
情報が多くなってくると CPUパワー使うだろうから、
リファラー情報は、ページが呼び出されるたびに記録し、
その集まった情報のソート、統計は 1日 1回流すように
してみました。

1日 1回なら cronで指定すれば良いから、お気楽な shスクリプトです。

以下のような shスクリプトをパスの通った所へ準備します。
私は /usr/local/binへ ref_count.shというファイルにしました。
#!/bin/bash
#

filedir=/home/localhost/access/data/
filename=bigdrive
outext=.txt

sort $filedir$filename | \
uniq -c | \
sort -r | \
grep -v search.yahoo. | \
grep -v www.google.co | \
grep -v search.nifty.com | \
grep -v search.msn.co | \
grep -v miya0.dyndns.org | \
grep -v legacy-b4.dyndns.org > $filedir$filename$outext
この書き方では、bigdriveというファイル名しか対応できないですね。
リファラー情報取りたいページが増えてきたら考え直します。

この shスクリプトが動くと、
/home/localhost/access/data/bigdriveに記録されたリファラー情報を
/home/localhost/access/data/bigdrive.txtへ一致した行をまとめ、多い順にソートし保存します。

以下のような bigdrive.txtというファイルが出来上がります。
     35
      6 http://blog.impulsebuyer.net/archives/2004/10/bigdrive.php
      3 http://win2k.pasokoma.jp/9_264363.html
      2 http://www.riznet.org/~kaoru/pukiwiki/pukiwiki.php?BigDrive%CC%E4%C2%EA
      2 http://www.kakaku.com/bbs/Main.asp?ItemCD=053840&MakerCD=52&Product=HD%2D250U2&CategoryCD=0538
      2 http://search.fresheye.com/?ord=s&rt=&query=&kw=bigdrive+%8A%EB%8C%AF
      1 http://www.infoseek.co.jp/OTitles?lk=noframes&qp=0&st=0&nh=10&col=OW&qt=windows2000+atapi.sys&svp=SEEK&svx=100600
      1 http://www.infoseek.co.jp/OTitles?lk=noframes&qp=0&st=0&nh=10&col=OW&qt=Windows2000%A1%A1BigDrive&svp=SEEK&svx=100600
      1 http://www.infoseek.co.jp/OTitles?col=OW&qt=bigdrive&svx=901908
      1 http://search.goo.ne.jp/web.jsp?MT=137G+%CA%C9&type=stick&PT=stick
      1 http://64.233.179.104/search?q=cache:rw7aa3vzeiUJ:b.hatena.ne.jp/keyword/Big%2520Drive%3Fsort%3Dhot+big+drive+xp&hl=ja&lr=lang_ja
      1 http://64.233.179.104/search?q=cache:hE-BaSyyqg8J:pasokoma.jp/bbs8/lg224079.html+win2000+%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E5%BE%8C%E3%80%80%E8%AA%8D%E8%AD%98%E3%80%80250GB&hl=ja&start=5

テキストファイルを表示するための CGI

ページの表示をしたとき、bigdrive.txtを表示するための CGIです。
以下のファイルを CGIの動作する場所へ保存します。
私は printfile.cgiというファイル名にしました。
#! /usr/bin/perl

$qst = $ENV{'QUERY_STRING'};
$filename = "data/$qst";

$ngstring ="\$";
$stringck = index $filename , $ngstring;
if ($stringck != "-1") {
exit;
}

$ngstring ="..";
$stringck = index $filename , $ngstring;
if ($stringck != "-1") {
exit;
}

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

open rfile , $filename;
while($_ = <rfile>){
chop;
print "document.write('$_');\n";
print "document.write('<br>');\n";
}
close rfile;

exit;

ページへ以下のように記述して CGIを呼び出すことにより、
data/ファイル名 の全行を表示します。
<script language="JavaScript" type="text/javascript" src="/access/printfile.cgi?bigdrive.txt"></script>

これから付けたい機能

表示されるリファラーの表示がリンクになってない
情報が沢山集まってくるとウザいのではないか? 検索エンジンを除外する機能を追加した方が良いかも?
どこかのサイトのアクセスログから飛んでくるような、表示しない方が良い情報をどう判別するか?

9282
戻る