class Ruboty::YMCrawl::Crawler

画像のスクレイピングを行うクラス

Constants

INDEX_STR

Public Class Methods

new(dir, site_data, wait_time) click to toggle source
# File lib/ruboty/ymcrawl/crawler.rb, line 118
def initialize(dir, site_data, wait_time)
        HostManager.instance.set_wait_time(wait_time)
        @selectors = {}
        @selectors[:image]          = site_data["css"]["image"].map          { |s| Selector.new(s) }
        @selectors[:image_title]    = site_data["css"]["image_title"].map    { |s| Selector.new(s) }
        @selectors[:title]          = site_data["css"]["title"].map          { |s| Selector.new(s) }
        @selectors[:page_index_max] = site_data["css"]["page_index_max"].map { |s| Selector.new(s) }
        @page_index_min             = site_data["page_index_min"]
        @next_page_appendix         = (site_data["next_page_appendix"] == nil) ? "" : site_data["next_page_appendix"]
        @dir = dir
end

Public Instance Methods

save_images(original_url) click to toggle source

与えられたcssセレクタから画像を抽出する

# File lib/ruboty/ymcrawl/crawler.rb, line 131
def save_images(original_url)
        dst_dir = "#{@dir}/#{get_contents(original_url, :title).first}"
        (@page_index_min..get_page_index_max(original_url) ).each do |page_index|
                url = "#{original_url}#{get_next_page_appendix_with_index(page_index)}"
                get_contents(url, :image).zip(get_contents(url, :image_title)) do |url, title|
                        save_image(dst_dir, url, title) unless url == nil
                end
        end
        dst_dir
end

Private Instance Methods

get_contents(url, target, nest = 0) click to toggle source

与えられたURLから、セレクタに従って画像のURLを返す

# File lib/ruboty/ymcrawl/crawler.rb, line 196
def get_contents(url, target, nest = 0)
        selector = @selectors[target][nest]
        if nest >= (@selectors[target].length - 1)
                return Page.new(url).search_elements(selector.to_s).map{ |cn| cn.get_content(target) } 
        end
        # 得られたURLそれぞれに対して次のセレクタを実行する
        contents = Page.new(url).search_elements(selector.to_s).map{ |cn| cn.get_content(:url) } 
        contents.map{ |c| get_contents(c, target, nest + 1) }.flatten
rescue Page::PageError => ex
        puts "error in get_contents #{ex}"
        return nil
end
get_next_page_appendix_with_index(index) click to toggle source

URLに付加する文字列を返す

# File lib/ruboty/ymcrawl/crawler.rb, line 181
def get_next_page_appendix_with_index(index)
        return "" if @next_page_appendix == ""
        @next_page_appendix.gsub("{index}", index.to_s)
end
get_page_index_max(url) click to toggle source

記事の最大ページを取得する

# File lib/ruboty/ymcrawl/crawler.rb, line 187
def get_page_index_max(url)
        # page_index_maxのcssが空文字だとget_contentsがエラーになるので、最初にチェック
        return @page_index_min if @next_page_appendix == ""
        page_index_max = get_contents(url, :page_index_max)
        return @page_index_min if page_index_max.length == 0
        (page_index_max.first.kind_of?(Integer)) ? page_index_max.first : @page_index_min
end
get_unique_name(dir, org_name) click to toggle source

ファイル名が既にimgディレクトリに存在していた場合はインデックスを付与する

# File lib/ruboty/ymcrawl/crawler.rb, line 144
def get_unique_name(dir, org_name)
        basename = (org_name == nil) ? "noname" : File.basename(org_name, '.*')
        ext = File.extname(org_name)
        return "#{basename}#{ext}" unless FileTest.exist?("#{dir}/#{basename}#{ext}")
        index = 1
        retname = "#{basename}#{index}#{ext}"
        while FileTest.exist?("#{dir}/#{retname}") do
                index = index + 1
                retname = "#{basename}#{index}#{ext}"
        end
        return retname
end
save_image(dst_dir, url, title) click to toggle source

指定されたリンク先の画像を保存する

# File lib/ruboty/ymcrawl/crawler.rb, line 158
def save_image(dst_dir, url, title)
        puts "src: #{url}"
        # ready filepath
        filename = "#{title}#{File.extname(url)}"
        filePath = "#{dst_dir}/#{get_unique_name(dst_dir, filename)}"
        HostManager.instance.wait(url)
        # fileName folder if not exist
        FileUtils.mkdir_p(dst_dir) unless FileTest.exist?(dst_dir)
        # write image adata
        begin
                open(filePath, 'wb') do |output|
                        puts "dst: #{filePath}"
                        open(URLUtil.normalize_url(url)) do |data|
                                output.write(data.read)
                        end
                end
        rescue # ファイルが存在しないなどの理由で例外が発生した場合は、生成した画像を削除
                puts "image not exist."
                File.delete filePath
        end
end