« Google Sitemaps  |   index   |  GoogleSitemapsジェネレータ »

2005年07月02日

サイト探索

Google Sitemaps ジェネレーターを作るにあたり、ネットワークから
サイト内のリンクをたどり、同一サイト内のURLを抽出するスクリプトを作ってみた

Code: download

  1. use LWP::Simple qw(get head);
  2. use HTML::LinkExtor;
  3. use strict;
  4.  
  5. my(%seen,%mod_time,%out,$site,$top_url);
  6. $top_url = 'http://sieg.xeong.com/';
  7. $top_url = "http://$top_url" unless $top_url =~ /^https?\b/;
  8. ($site = $top_url) =~ s/^(http:\/\/.+\/).*$/$1/;
  9. $site .= "/" unless ($site =~ /\/$/);
  10.  
  11. linker($top_url);
  12.  
  13. sub linker {
  14.  my $base_url = shift;
  15.  my $parser = HTML::LinkExtor->new(undef, $base_url);
  16.  $parser->parse(get($base_url))->eof;
  17.  my @links = $parser->links;
  18.  for my $linkarray (@links) {
  19.    my @element = @$linkarray;
  20.    my $elt_type = shift @element;
  21.    while(@element) {
  22.      my ($attr_name, $attr_value) = splice(@element, 0,2);
  23.      if(  $attr_name eq "href" && $attr_value->scheme =~ /\b(https?)\b/ && $attr_value =~ /^$site/){
  24.        #   && ($attr_value =~ /\.xml?$/i or $attr_value =~ /\.s?html?$/i or $attr_value =~ /\.php.*$/i or $attr_value =~ /\.cgi.*$/i)){
  25.        $attr_value =~ s/^(.+)#.*$/$1/;
  26.        next if(defined $seen{$attr_value});
  27.        my @heads = LWP::Simple::head($attr_value);
  28.        if(@heads) {
  29.          $seen{$attr_value}++;
  30.          my @date = $heads[2] ? gmtime($heads[2]) : gmtime(time);
  31.          $mod_time{$attr_value} = sprintf("%04d-%02d-%02dT%02d:%02d:%02dZ", $date[5]+1900, $date[4]+1, @date[3,2,1,0]);
  32.        }
  33.      }
  34.    }
  35.  }
  36.  
  37.  for (sort keys %seen) {
  38.    my $mod = $mod_time{$_};
  39. #    s/^(.+\.cgi).*$/$1/i;
  40. #    s/^(.+\.php).*$/$1/i;
  41.    if(defined $out{$_}) {
  42.      next;
  43.    } else {
  44.      $out{$_} = 'true';
  45.      print qq($_ - $mod\n);
  46.      linker($_);
  47.    }
  48.  }
  49. }

使い方
6行目で探索するURLを指定
Windowsではコマンドラインから、これを実行するとリンクリストとUTC時間を表示する

Windowsコマンドプロンプトでのテキストファイル(link.txt)への出力例
perl -w linkgen.pl > link.txt


環境
以下のperlモジュールが必要
LWP::Simple
HTML::LinkExtor

解説
6行目: $top_urlに探索したいサイトのトップページを指定する
以下9行目までは、URLの補間処理
11行目: サブルーチン linker 実行

linker:
15,16行でページ内のリンクリストを取得、このリストは17行目 @links に格納
23行目で href属性 内の http又はhttps で始まり、サイトの url を含むものだけに分類
24行目はコメントアウトしてあるが、はずすと xml,htm,html,shtm,shtml,php,cgi だけに絞り込める (その際23行目後ろの2文字は取り去ること)
25行目でページ内リンク(アンカー)を取り去る
26行目重複を確認(再帰しているのでこれを怠ると止まらなくなる)
27行目でヘッダ情報を取得
29行目も重複対策 (%seenに格納)
30行目は対象ページの最終更新日からGMTタイムを取得
31行目で整形して %mod_time に格納
38行目は、以下2行をコメントアウトした場合の対策としての位置
39,40行目は、コメントアウトしているがCGIとPHPへの変数を削除
以下4行は、更に重複を確認 (心配性です)
45行目で出力 形式は 完全URL - UTCタイム
46行目で再帰

注意
しつこいようだが再帰処理しているので、改変時には注意を
サイトの構成、ネットワークの状態にもよるが かなり時間がかかるはず
できるだけ、コメントアウトしているところを実行させるほうがいい
27行目: LWP::Simple::headとしているのはCGI.pmのheadとの名前衝突回避のため

参照
UTCタイムについて、W3CのDate and Time Formatsを参考にした
Link::Extorについては Perldoc と、河馬屋二千年堂さんの日本語訳
LWP::Simple については言うまでもないだろう

方向性
これから、Google Sitemaps ジェネレーターを作っていこうと思っているわけで
とりあえずは、URLの抽出と ISO 8601形式の時間換算をやってみた
次は簡単 Google Sitemaps (BETA) Help
グーグル・サイトマップ(ベータ版)FAQとプロトコル全訳
を参考にXMLタグを組むだけ 今度はCGIにしようと思う


投稿者 edams : 2005年07月02日 03:37

トラックバック

このエントリーのトラックバックURL: http://sieg.xeong.com/mt-tb.cgi/21
このエントリーを含むはてなブックマークこのエントリーを含むはてなブックマーク


コメント

サイン・インを確認しました、 さん。コメントしてください。 (サイン・アウト)

(いままで、ここでコメントしたとがないときは、コメントを表示する前にこのウェブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)


情報を登録する?