Ruby - ウェブスクレイピング - リンク切れをチェック 基本
- 1. 概要
- 2. ソースを3分割2
- 3. リンク URI を抽出する
- 4. リンク先をチェックする
- 5. 現時点での実行結果
1. 概要
第一段階の目標点が、前ページまでで取得したリンクをチェックして、リンク切れが発生していないかを調べるというものなのです。
「Ruby - サイト内リンク切れチェック!」にまんまみたいなものがありますが、参考にしながら。
2. ソースを3分割に
とりあえず、ソースを3つに分けました。
まず、メイン。
コマンドライン引数を受け取って渡す部分。
#!/usr/bin/env ruby
require './checkparent'
tree = { ARGV[0] => 'UNKNOWN' }
parent = CheckParent.new()
parent.do(ARGV[0], tree)
5行目の tree という連想配列は、まだできていませんが、ドメイン内のリンクであれば再帰的にたどって、リンク切れを探すようにしたいので。
再帰的にたどるなかで既にチェック済の URI かどうか判定するためにチェック済の URI をためる配列です。
3. リンク URI を抽出する
この章の前の方で作成した部分をクラス化して、リンク URI を抽出するようにしました。
#!/usr/bin/env ruby
require './checkchild' ← リンク先をチェックするクラス
require 'open-uri'
require 'nokogiri'
class CheckParent
def initialize()
end
def do(uri, tree)
begin
tree.each { | key, value | ← ここらでチェック済かどうかを判定している
if (key == uri)
if (value != 'UNKNOWN')
return; ← 判定済であれば処理しない
end
end
}
uri = URI.encode(uri) ← ここからリンク先を抽出
uri = URI.parse(uri)
html = open(uri).read
html.sub!(/^<!DOCTYPE html(.*)$/, '<!DOCTYPE html>')
doc = Nokogiri::HTML(html)
link = []
doc.css('a').each do |anchor|
link.push(anchor[:href])
end
doc.css('input').each do |anchor|
if s = anchor[:onclick]
s = s[/\'.*\'/]
link.push(s.delete!("'"))
end
end
doc.css('img').each do |anchor|
link.push(anchor[:src])
end
link.sort!
check = Check.new() ← リンク先をチェック
check.do(uri, link)
← この先でドメイン内のコンテンツであれば再帰的にリンクチェックしたい
rescue => error
puts "例外発生"
puts "#{error.backtrace}"
puts "[#{self.class.name}][#{error.message}]"
exit 1
end
end
end
4. リンク先をチェックする
前項からの呼び出し先、リンクをチェックする部分。
これが全然未完なのですが・・・。
#!/usr/bin/env ruby
require 'open-uri'
require 'nokogiri'
class Check
def initialize()
end
def do(parent, child)
res = 'OK'
for item in child do
case item[0]
when '#'
# puts "ページ内リンク => #{item}"
# ページ内リンクなので html 内に id=item が存在すること
when 'h'
# 外部リンクなので存在の有無のみ
res = fetch(item)
puts "外部 リンク => #{item} 結果[#{res}]"
else
if item[-3, 3] == 'png'
# puts "イメージファイル => #{item}"
# イメージなので存在の有無のみ
elsif item[-4, 4] == 'html' || item[-1, 1] == '/'
# puts "内部 リンク => #{item}"
# 内部リンクなので可能であればたどりたい
else
# puts " => #{item}"
# 上記以外なのでチェックしない
end
end
end
end
private
def fetch(url)
begin
uri = URI.encode(url)
uri = URI.parse(uri)
open(uri)
rescue OpenURI::HTTPError => error
return 'NG'
rescue => error
puts "例外発生"
puts "#{error.backtrace}"
puts "[#{self.class.name}][#{error.message}]"
exit 1
end
return 'OK'
end
end
5. 現時点での実行結果
現時点で実行してみます。
わざと、リンク先がないものをいれています。
./ソースファイル名.rb http://freebsd.sing.ne.jp/windows/01/99.html
外部 リンク => http://net-3.blogspot.jp/2013/03/blog-post_16.html 結果[OK]
外部 リンク => http://net-3.blogspot.jp/2013/03/blog-post_99.html 結果[NG]
|
|