1.023world - ヤドカリパークとマリンアクアリウム -

海洋の仕組みと細菌・微生物から学ぶマリンアクアリウムサイト

1.023world Facebook

結果 Oh! Life (旧ブログ)

懲りずに書いてみたりする結果オーライな日記

静的サイトのためのRORサイトマップ生成CGI

最近はアクアショップサイトなんかでもCMSの利用が増えてきましたが、それでもまだ古式ゆかしく静的なHTMLをソフトまたは手打ちでシコシコ作成しておられるショップサイトも少なくないでしょう (間違ってもバカにしてるつもりはありませんし、むしろ尊敬します)

そんなショップさんを応援すべく、少しでも他の CMS サイトに負けないためにも、ROR 形式のサイトマップXML(検索エンジン対策)を自動で生成してくれる CGI を作ってみました。
まずは流れを知るために、以下の解説を順にご覧ください。

ROR サイトマップとは?

以下のソースのような XML ファイルです。

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:ror="http://rorweb.com/0.1/">
  <channel>
    <title>ROR Sitemap for http://www.1023world.net/</title>
    <link>http://www.1023world.net/</link>
    <item>
      <link>http://www.1023world.net/</link>
      <ror:updated>2009-02-28T18:54:48+00:00</ror:updated>
      <ror:updatePeriod>weekly</ror:updatePeriod>
      <ror:sortOrder>0</ror:sortOrder>
      <ror:resourceOf>sitemap</ror:resourceOf>
    </item>
  </channel>
</rss>
</rss>

これは当サイトの場合のソースの抜粋例ですが、実際にはページ数の分だけソースは繰り返し長くなります。
内容的には、どのページがいつ更新されたか、そして更新頻度はどうか、みたいな情報がXMLの構文で羅列されています。
この XML ファイルをサーバーに置いて検索エンジンに渡すことで、リストされたサイト内のページをもれなくクロールさせることができます。

ROR 形式のサイトマップは、Google、Yahoo、MSN、すべての検索エンジンで利用可能な汎用フォーマットなので、これからサイトマップの準備を検討される方にはおすすめなフォーマットです。
ちなみにアクアショップさんじゃない方でも、必要であればご自由にお使いください (サポートはしませんが)

RORサイトマップ作成CGI 特長

  • CGI をサーバーに置いて呼び出すだけでRORサイトマップを自動生成
  • 簡易認証機能があるので、他人に実行させない
  • 他のサーバーにURLを送ったり、生成時にソースをコピーしたりファイルを作成したり等の手間が一切不要

RORサイトマップ作成CGI 利用条件

  • 独自ドメインの方
  • サーバーで CGI が使えること
  • サーバーに Jcode.pm がインストールされていること

RORサイトマップ作成CGI 設置手順

  1. CGI のプログラムソースをメモ帳(あるいはテキストエディタ等)にコピペして「setSitemap.cgi」と言う名前で保存します。
  2. 必要であればご利用のサーバーに合わせて1行目の Perl のパスを書き換えます。
    #!/usr/bin/perl または #!/usr/local/bin/perl など)
  3. 次に8行目のパスワードをあなただけのモノに必ず書き換えておいてください。
  4. 万一、サイトマップで除外したいページがある場合は、14行目の @no と言う配列にファイル名またはディレクトリ名をルートからの絶対パスで追加してください。
    例えば、http://あなたのドメイン/secret.html を除外したければ、 /secret.html を追加します。
    また、http://あなたのドメイン/member/ 内のすべてのページを除外したければ、/member/ を追加します。
    (これらの例を既にソースに入れてあります)
  5. 作成した CGI ファイルを、サーバーのルート(トップページを置いてる階層)にアップロードします。
  6. CGI ファイルのパーミッション(アクセス権)を 755 にします。
    (サーバーによっては 755 以外の場合があります)
  7. http://あなたのドメイン/setSitemap.cgi?パスワード にアクセスします。このURLが今後サイトマップを更新するURLとなります。
    仮にあなたのドメインが abc.com で、パスワードを abcd1234 としたなら、http://abc.com/setSitemap.cgi?abcd1234 へのアクセスとなるはずです。
    このアクセスにより、その時点でのサイトマップが ror.xml と言うファイル名でルートに生成(更新)されます。
    生成後のサイトマップのURLは http://あなたのドメイン/ror.xml です。
    (Firefoxだとタイトルしか出ないかも知れませんが、ソースを開けばサイト内のページがすべてリストアップされているのが確認できると思います)
  8. 続いて、あなたのサイトのトップページのヘッダ内(<head>この中</head>)に、以下のタグを埋め込んでおきます。改行せずに一行で書いてもOKです。
    <link rel="alternate" type="application/rss+xml"
    href="http://あなたのドメイン/ror.xml" title="ROR 0.1" />

    これで、次回の検索エンジンのクロールでサイトマップが読み込まれ、リストされたすべてのページが今後のクロール対象となるでしょう。
    あとは、今後サイトを更新するたびに 7. へアクセスして、その都度サイトマップを最新のモノに更新しておいてください。

RORサイトマップ作成CGI のプログラムソース

#!/usr/bin/perl

### make: http://YOURDOMAIN/setSitemap.cgi?(password)
### view: http://YOURDOMAIN/ror.xml
##################################################

### password
my $pwd = "abcd1234";   # set your original password.

### ROR file name
my $ror = "ror.xml";

### noindex files or directory, from root path.
my @no = (
  "/secret.html",
  "/member/",
);

### updatePeriod:
### always,hourly,daily,weekly,monthly,yearly,never
my $up = "monthly";

##################################################

use Jcode;

&viewXML if ($ENV{'QUERY_STRING'} ne $pwd);

my $no = ",." . join(",.",@no) . ",";

my(@html,$xml);
&getHTML("./");
&setXML;

print qq|Content-type: text/xml; charset="UTF-8"\n\n$xml|;
exit;

sub viewXML {
  print "Location: http://$ENV{'HTTP_HOST'}/$ror\n\n";
  exit;
}

sub getHTML {
  my $dir = $_[0];
  my @file = &getDir($dir);
  foreach my $file (@file) {
    my $path = "$dir$file";
    next if ($no =~ /,\Q$path\E\/?,/);
    &getHTML("$path/") if (-d $path);
    next if ($file !~ /\.html?$/i);
    my $last = (stat($path))[9];
    $path =~ s/^\.+|(\/)index\.html?$/$1/ig;
    push(@html,"$last\t$path\t$up\t\n");
  }
}

sub setXML {
  @html = reverse sort @html;
  foreach (@html) {
    my($last,$path,$up) = split(/\t/,$_);
    my($year,$mon,$day,$hour,$min,$sec) = &getTime($last);
    $last = "$year-$mon-$day" . "T$hour:$min:$sec+09:00";
    $xml .= <<"EOF";
		<item>
			<link>http://$ENV{'HTTP_HOST'}$path</link>
			<ror:updated>$last</ror:updated>
			<ror:updatePeriod>$up</ror:updatePeriod>
			<ror:sortOrder>0</ror:sortOrder>
			<ror:resourceOf>sitemap</ror:resourceOf>
		</item>
EOF
  }
  $xml = <<"EOF";
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:ror="http://rorweb.com/0.1/">
	<channel>
		<title>ROR Sitemap for $ENV{'HTTP_HOST'}</title>
		<link>http://$ENV{'HTTP_HOST'}/</link>
$xml	</channel>
</rss>
EOF
  &setFile("./$ror",Jcode->new($xml)->utf8);
}

sub getDir {
  my $dir = $_[0];
  opendir(DIR,$dir) || return ();
  @_ = sort readdir DIR;
  closedir(DIR);
  splice(@_,0,2);
  return @_;
}

sub setFile {
  my($file,@data) = @_;
  open(OUT,"> $file");
  seek(OUT,0,0);
  print OUT @data;
  truncate(OUT, tell(OUT));
  close(OUT);
  chmod(0666,$file);
}

sub getTime {
  my $time = $_[0];
  $ENV{'TZ'} = "JST-9";
  my($sec,$min,$hour,$day,$mon,$year,$week) = localtime($time);
  $year += 1900;
  $mon = sprintf("%02d",$mon+1);
  $day = sprintf("%02d",$day);
  $hour = sprintf("%02d",$hour);
  $min = sprintf("%02d",$min);
  $sec = sprintf("%02d",$sec);
  $week = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat')[$week];
  return ($year,$mon,$day,$hour,$min,$sec,$week);
}

うまくコピペできない場合は、こちらを開いてご利用ください。

注意事項など

  • 静的HTMLではないサイト構造の方(ブログ等)は利用できません。あくまでHTMLファイルが対象です。
  • サイトマップの生成にはサーバーにある程度の負荷が掛かるので、必ずパスワードを設定して自分だけがアクセスできるようにしてください。また、自分以外の方が触るパソコンでは、サイトマップ更新用URLはブックマークしない方が無難です。
    ちなみにパスワード無し(あるいは間違えると)でアクセスすると、ror.xml にジャンプする仕組みになっています。
  • サイト内のすべてのページ(拡張子が .htm.html のもので大文字小文字問わず)が全て対象になるので、都合の悪いページは予め @no に設定しておいてください。
  • サイトマップの生成に要する時間はページの量に応じて長くなります。
  • サイトマップはページの更新日時順に降順でソートされます。
  • CGI ファイルを作成する際の文字コードは意識する必要はありません (Shift_JIS でOK)
  • updatePeriod 要素は全ページ共通の設定となります。weekly か monthly あたりで良いと思いますけど。
  • sortOrder 要素は全ページ 0 を割り当てています。これは0以外を入れたらどうなるのかよく判りません(汗)
  • プログラムはソースを簡潔にするため、必要最小限の構成となっています。不便な点や改良点があれば自由にいじってお使いください。
  • なるべくサーバーに依存しないように組んでありますが、最低限 Jcode が使えるサーバーが必要です。
  • 尚、全てのサーバーでの動作を保証するモノではありませんので、解説通りに設置して動かない場合は諦めてください(汗)
    但し、海水関連ショップの方ならご相談に載ります。
    info@1023world.net まで。

その他、何かあればコメント欄にどうぞ。

こちらのエントリーもどうぞ♪