专注收集记录技术开发学习笔记、技术难点、解决方案
网站信息搜索 >> 请输入关键词:
您当前的位置: 首页 > Ruby/Rails

使用RUBY+WATIR写的代码运行时间长了之后IE的内存就会越来越大!解决思路

发布时间:2011-06-29 18:43:59 文章来源:www.iduyao.cn 采编人员:星星草
使用RUBY+WATIR写的代码运行时间长了之后IE的内存就会越来越大!
莪使用RUBY+WATIR编写了一个自动化检测某网站的缺货商品的脚本、但程序时间运行一长、就会使得IE的内存变得越来越大、最大的情况下甚至超过了1G!、导致IE错误而无法继续运行下去、目前尚不知道是不是RUBY的垃圾回收的机制造成的BUG还是自己程序造成的BUG、请大家一起来帮忙看看、使用的RUBY版本是1.8.7、而WATIR的版本是1.9.1

简要说明一下该软件的功能、
该软件的功能是检测出走秀网的所有活动页上的产品是否缺货、
缺货的依据是根据页面返回的JS、查看是否存在link的ID为no_goods的连接、有则返回缺货、
然后通过OCI8的插件把产品写入ORACLE数据库里头

Python code

require "rubygems"
require "watir"
require 'oci8'


day = 86400
hour = 3600
minute = 60

##四小时执行一次
time = hour * 4


loop {
    begin
        ##所有活动页的地址
        all_links = []
        ##活动页下的所有单品地址
        links = []
        ##所有单品的地址
        all_prd_links = []

        ##所有缺货地址
        gustnames = []
        product_codes = []
        product_urls = []
        channel_links = []
        channel_names = []
        ##单个活动页缺货个数
        no_goods = 0
        ##数组的序列号
        list_num = 0

        ##所有产品缺货个数
        ##所有产品名称
        ##所有产品商品编码
        ##所有产品地址

        all_no_goods = 0
        all_gustnames = []
        all_product_codes = []
        all_product_urls = []
        ##商品编号
        goods_id = 0

        ######################################################################
        ##################    从links文本文件中获取所有活动页地址   ##########
        ######################################################################
        ##return all_links

        def get_all_links
          all_links = []
          
          io_f = File.open("links.txt", "r")
          while line = io_f.gets
            ##消除换行符
            line.chomp!
            all_links.push line
          end
          io_f.close
          
          return all_links
        end

        ######################################################################
        ##################    循环访问网页   #################################
        ######################################################################
        ##return [no_goods, gustnames, product_codes, product_urls]

        def found_noprd_links(links)
          
          no_goods = 0
          
          #gustname为缺货产品名称
          #product_code为缺货产品商品号
          #product_url为缺货产品所在地址
          
          gustnames = []
          product_codes = []
          product_urls = []
          
          
          links.each { |link|
            $ie.goto link
            if $ie.link(:id, "no_goods").exists?

                
                gustname = $ie.div(:class, "top").h1(:index,1).text
                
                ###   有时有些缺货产品会出现没有TD为2的情况导致出错  #############33
                if $ie.div(:id, "product_price_area").cell(:index,2).exists?
                  product_code = $ie.div(:id, "product_price_area").cell(:index,2).text
                  else
                  product_code = $ie.div(:id, "product_price_area").cell(:index,1).text
                end
                product_url = $ie.url
                
                ##########      去掉商品号中的汉字         ###################
                del_str = "商品编号:"
                product_code = product_code.delete(del_str)
                
                 gustnames.push gustname
                 product_codes.push product_code
                 product_urls.push product_url
               
                ######      假如发现缺货产品、no_goods加一      #################
                no_goods = no_goods + 1
                
            end
          }
          
          return [no_goods, gustnames, product_codes, product_urls]

        end


        ######################################################################
        ##################    获取当前活动页所有单品地址   ###################
        ######################################################################
        ##return links

        def get_prds
          if $ie.div(:id, "bd").exists?
            links = []
            #####显示出当前网页所有链接
            $ie.div(:id, "bd").links.each { |link_element|
              #######查找是否为产品页链接
              if link_element.to_s.include? "http://www.xiu.com/product"
                #######把产品页链接提取出来
                link_element.to_s.each { |link|
                  if link.include? "href"
                    link.sub!(/href:         /, '')
                    links.push link
                    break
                  end
                }
              end
              
            }
            
            ##图片和文字一共会有两个不同的链接
            links= links.uniq
            return links
          end
        end




        ##################################################################################################################################################################
        ##################################################################################################################################################################
        ##################################################################################################################################################################

        $ie = Watir::IE.new
        
        $ie.minimize

        all_links = get_all_links

        all_links = all_links.uniq


        all_links.each { |link|
          
          $ie.goto link
          
          links = get_prds

          no_goods,gustnames,product_codes,product_urls = found_noprd_links(links)
          
          all_no_goods = all_no_goods + no_goods
          all_gustnames.concat gustnames
          all_product_codes.concat product_codes
          all_product_urls.concat product_urls

          ##保持活动页与单品页同步
          
          $ie.goto link
          
          
          no_goods.times{
            channel_links.push $ie.url
            channel_names.push $ie.title
          }
          
          puts $ie.url
          puts $ie.title
          
        }

        $ie.close

        #channel_links,channel_names, all_gustnames, all_product_codes, all_product_urls


        ##把缺货产品写入ORACLE中
        if all_no_goods > 0
          channel_links.each {
              
              channel_name = channel_names[list_num]
              channel_url = channel_links[list_num]
              goods_code = all_product_codes[list_num]
              goods_name = all_gustnames[list_num]
              goods_url = all_product_urls[list_num]
              goods_id = goods_code[0..6]
              
              ##把单引号转化成两个单引号、以顺利输入进ORACLE数据库
              if goods_name.index("\'") != nil
                goods_name = goods_name.gsub(/'/, "\'\'")
              end
            
              if channel_name.index("\'") != nil
                channel_name = channel_name.gsub(/'/, "\'\'")
              end
              
              
              #~ puts channel_name
              #~ puts channel_url
              # puts goods_code
              #~ puts goods_name
              #~ puts goods_url
              
              
              
                activity_page_sql = "INSERT INTO TBL_SOLDOUT_ACTIVITY_PAGE
                VALUES
                  (SEQ_TBL_SOLDOUT_ACTIVITY_PAGE.NEXTVAL,\'" <<
                   channel_name.to_s << "\',\'" <<
                   channel_url.to_s << "\',\'" <<
                   goods_code.to_s << "\',\'"<<
                   goods_name.to_s << "\',\'"<<
                   goods_url.to_s << "\',SYSDATE,\'"<<
                   goods_id<< "\')"

                ##并把错误日志文件保存在本目录下
                host_bak_name = "log_sql.txt"
                
                ##保存SQL文件
                bak_data = Time.now.to_s << "_____" << activity_page_sql
                ##文件参数使用"a"、意思是说如果存在文件、则追加结果而不是覆盖
                io = File.open(host_bak_name, "a")
                io.puts(bak_data)
                io.close
                
                conn = OCI8.new("name", "password", "xiu")
                conn.exec(activity_page_sql)
                conn.commit
                conn.logoff
                
                list_num = list_num + 1
            
            }
              
             
        end
    puts Time.now

    ##处理异常
    rescue  Exception => e
            ##如果发生错误、保存错误日志
            puts e.message
            
            ##并把错误日志文件保存在本目录下
            host_bak_name = "log_err.txt"

            ##保存文件
            bak_data = Time.now.to_s << "_____" << e.message
            ##文件参数使用"a"、意思是说如果存在文件、则追加结果而不是覆盖
            io = File.open(host_bak_name, "a")
            io.puts(bak_data)
            io.close
            $ie.close
            ##如果由于网速原因导致运行停止、重新再执行
            retry
    end
#睡觉时间
#######################################
    sleep time
}



友情提示:
信息收集于互联网,如果您发现错误或造成侵权,请及时通知本站更正或删除,具体联系方式见页面底部联系我们,谢谢。

其他相似内容:

热门推荐: