リンク集をまとめる作業

これまでにいくつかデータを取ってきましたが,いくつかのものはリンク集として使えそうだったので自サイトでのカテゴライズなどをちょこちょこ変更中です.

リンク集は更新が保てている間は便利なのですが,(掲載されているページに)リンク切れが頻発するようになると使い物のにならなくなると言う問題点があります.リンク切れのチェックは http://deadlink.tv/index.php のような Web サービスも存在するのですが,1 ページに書かれてある量が多くなってくるとやはりローカルでチェックしないとしんどくなってきます.

Ruby だとこんな感じで書くと簡易のリンク切れチェックになりそうです.

#!/bin/ruby -Ku
require 'cgi'
require 'open-uri'
require 'rubygems'
require 'nokogiri'

# --------------------------------------------------------------------------- #
#
#  get_urilist
#
#  指定した URL から取得できる html に記述されている全 URL を取得して
#  配列で返す.取得方法は,Nokogiri で全ての a タグを走査すると言うもので,
#  走査した a タグに記述されてある URL のうち,host と path が存在する
#  ものだけを対象とする.
#
# --------------------------------------------------------------------------- #
def get_urilist(uri)
    begin
        results = Array.new
        open(uri) { |f|
            html = Nokogiri::HTML.parse(f.read)
            elements = html.search("a")
            break if (elements == nil || elements.length == 0)
            
            elements.each { |node|
                next if (node['href'] == nil)
                
                link = node['href'].strip
                parser = nil
                begin
                    parser = URI.parse(link)
                rescue URI::InvalidURIError
                    parser = URI.parse(URI.encode(link))
                end
                next if (parser == nil || parser.host == nil || parser.path == nil)
                results.push(link)
            }
        }
        return results
    rescue Exception
        nil
    end
end

# --------------------------------------------------------------------------- #
#  main
# --------------------------------------------------------------------------- #
begin
    raise "usage link-checker.rb url" if (ARGV.length < 1)
    
    v = get_urilist(ARGV[0])
    exit if (v == nil || v.length == 0)
    
    unknown = Time.local(1970, 1, 1, 0, 0, 0)
    v.each { |uri|
        begin
            open(uri) { |f|
                time = (f.last_modified != nil) ? f.last_modified : unknown
                puts("\"#{f.status[0]}\",\"#{time.to_s}\",\"#{uri}\"")
            }
        rescue Exception
            next
        end
    }
rescue Exception => e
    $stderr.puts(e.message)
end
実行結果
$ ruby link-checker.rb http://cielquis.net/
"200","Fri Feb 25 15:29:57 +0900 2011","http://clx.cielquis.net/"
"200","Mon May 02 09:16:27 +0900 2011","http://d.hatena.ne.jp/tt_clown/"
"200","Tue May 03 18:07:46 +0900 2011","http://twitter.com/home?status=%40tt_clown"
"200","Mon May 02 09:16:27 +0900 2011","http://d.hatena.ne.jp/tt_clown/"
"200","Tue May 03 18:07:49 +0900 2011","http://twitter.com/tt_clown"
"200","Thu Jan 01 00:00:00 +0900 1970","http://www.facebook.com/tt.clown"
"200","Fri Feb 25 15:29:57 +0900 2011","http://clx.cielquis.net"
"200","Sat Nov 27 01:59:55 +0900 2010","http://www.1christmas.org/"