使用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
}