Ruby - リンクチェック - checkparent.rb ドキュメントからリンク先を抽出

クラウディア 
1. ドキュメントからリンク先を抽出

1. ドキュメントからリンク先を抽出

 上から渡された、URI のドキュメントを読みこんでリンク先を抽出してチェックするクラスへ渡します。  ここが再帰呼び出しの起点になります。
=begin

指定の URI を取得して、ドキュメント内のリンク先を抽出する

=end

require('pry')
require('checkchild')
require('exceptlog.rb')
require('open-uri')
require('nokogiri')

class CheckParent
  def initialize(original)
    @check = Check.new(original)
  end

  def execute(uri, tree, checked)
    begin

      tree.each do | key, value |
        if (key == uri)
          if (value != 'UNKNOWN')
            return;
          end
        end
      end

      tree[uri] = 'CHECKING'

      if ($nocheckParent.grep(uri) != [])
        return;
      end

      originalURI = uri

      now = Time::now()
      nowtime = sprintf("%02d",now.hour)+":"+sprintf("%02d",now.min)+":"+sprintf("%02d",now.sec)
      print("#{nowtime} #{originalURI} ")

      uri = URI.encode(uri)
      uri = URI.parse(uri)

      print(".")

      html = open(uri).read
      html.sub!(/^<!DOCTYPE html(.*)$/, '<!DOCTYPE html>')
      doc  = Nokogiri::HTML(html)

      link = {}

      doc.css('a').each do | tag |            # <a href="URI"> の URI の部分を取得
        link[tag[:href]] = nil
      end

      #binding.pry

      doc.css('input').each do | tag |        # <input onclick="location.href='URI'"> の URI の部分を取得
        work = tag

        if (!work.kind_of?(Hash))
          work = tag.attributes

          if (!work.kind_of?(Hash))
            next                              # Hash でないとき以下を処理すると落ちるよ
          end
        end

        if work.has_key?('onclick')
          if s = work['onclick'].value
            begin
              s = s[/\'.*\'/]

              if (s == nil)                   # OnClick="JavaScript: ..." のようなケースはリンク URI でないため nil となる
                next
              end

              link[s.delete!("'")] = nil
            rescue => error
              exeptlog = ExceptLog.new
              binding.pry
              exeptlog.execute(self, error)
              exit 1
            end
          end
        end
      end

      doc.css('img').each do | tag |          # <img src="URI"> の URI の部分を取得
        link[tag[:src]] = nil
      end

      # 広告の URI はチェックしない処理

      link.each_key do | key |
        if ((key.include?('.a8.net')) ||      # a8.net
            (key.include?('afi-b.com')))      # afi-b
          link.delete(key)
        end
      end

      # 何故か nil をキーに持つものが発生することがある
      # nil をキーに持つものがあると sort 時に例外が発生するので delete する
      # nil をキーに持つものがなぜできるかは別途調査が必要かも・・・

      #puts("\t\t#{link} \n")

      link.delete(nil)
      link = Hash[link.sort]

      @check.execute(originalURI, doc, link, tree, checked)

    rescue OpenURI::HTTPError => error
      puts("  #{uri} ")
      puts("例外発生[#{error.class}]")
      #$result[uri] = { :リンク元 => parent, :種別 => '不明', :リンク => uri, :結果 => 'unknown' }

    rescue SocketError, Errno::ECONNRESET, Net::OpenTimeout, NoMethodError, ArgumentError => error
      #binding.pry
      puts("  #{uri} ")
      puts("例外発生[#{error.class}]")

    rescue => error
      exeptlog = ExceptLog.new
      binding.pry
      exeptlog.execute(self, error)
      exit 1
    end
  end
end