读书人

运用RUBY+WATIR写的代码运行时间长了之

发布时间: 2013-01-02 13:08:44 作者: rapoo

使用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数据库里头


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
}





[解决办法]
是你输出的内容太多, IE运行于客户端, 也不可能本身ruby问题, 是代码里人为的出错
[解决办法]
这是IE内存管理的问题,和你没有关系了。IE怎么用,内存一般都是自增的。

读书人网 >Ruby Rails

热点推荐