http では、リクエストの方法としては get と post がよく知られている。 そのほかに、head というリクエストがあるがこれはあまり知られていない。 head は該当 URL のヘッダのみを取り込むリクエストで、get や post に比べて取得するデータ量が少なくてよい。 その結果、WEB サーバに負担をかけずにすむ。今回はリンクのありなしと更新の有無を見るだけなので、 head リクエストが適切と判断した。
私が以前書いたリンク切れチェッカーである。解説は後ほど追加する。
require 'net/http' require 'uri' require 'time' timelag = 5 # timelag 秒以内の差であれば、不正確なlast-modifiedとみなす origin = '1970-01-01T09:00:00+09:00' hash = Hash.new ARGF.each {|line| if (line =~ /^<tr><td><a href="(.*)".*/) url = $1 uri = URI.parse(url) host = uri.host path = uri.path # print "<tr><td><a href=\"#{url}\">#{url}</a></td>" begin h = Net::HTTP.new(host, 80) resp = h.head2(path, nil) lm = resp['last-modified'] dt = resp['date'] ct = resp['content-length'] lm = origin if lm == nil if (Time.parse(lm).to_i - Time.parse(dt).to_i).abs < timelag lm = origin end # print "<td>#{(Time.parse(lm)).iso8601}</td><td>#{resp.code}</td></tr>\n" # ハッシュの値は配列。 hash[url] = [Time.parse(lm).to_i, resp.code, ct] rescue hash[url] = [0, 0, 0] # rescue SocketError # hash[url] = [0, 0, 0] # rescue NameError # hash[url] = [0, 1, 0] end elsif (line =~ /end of links/) sorted = hash.sort{|a,b| b[1][0] <=> a[1][0]} # エポック秒が大きいものから sorted.each {|key, value| url = key print "<tr><td><a href=\"#{url}\">#{url}</a></td>" print "<td>#{Time.at(value[0]).iso8601}</td><td>#{value[1]}</td><td>#{value[2]}</td></tr>\n" } print line else puts line end }
まりんきょ学問所 > Rubyの浮き輪 > リンク切れチェッカー