我只是检查页面上元素的存在:
sleep 5 # for the page load
form.wait_until_present
next if form.span(:class => "SSSMSGWARNINGTEXT").exists?
form
来自这两行:
browser.goto browser.frame(:name => "TargetContent").src
form = browser.form(:name => "win1")
前一页和当前页都有form
,所以我添加了一个睡眠以确保它有新页面。但是,我的程序仍然因错误而崩溃:
[remote server] resource://fxdriver/modules/web_element_cache.js:5665:in `unknown': Element not found in the cache - perhaps the page has changed since it was looked up (Selenium::WebDriver::Error::StaleElementReferenceError)
from [remote server] file:///var/folders/80/_bwll9x91h7d6c5dp2d3fbb00000gr/T/webdriver-profile20120724-63693-194o52g/extensions/fxdriver@googlecode.com/components/driver_component.js:5354:in `unknown'
from [remote server] file:///var/folders/80/_bwll9x91h7d6c5dp2d3fbb00000gr/T/webdriver-profile20120724-63693-194o52g/extensions/fxdriver@googlecode.com/components/driver_component.js:6597:in `unknown'
from [remote server] file:///var/folders/80/_bwll9x91h7d6c5dp2d3fbb00000gr/T/webdriver-profile20120724-63693-194o52g/extensions/fxdriver@googlecode.com/components/driver_component.js:471:in `unknown'
from /Users/amosng/.rvm/gems/ruby-1.8.7-p370/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/response.rb:52:in `assert_ok'
from /Users/amosng/.rvm/gems/ruby-1.8.7-p370/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/response.rb:15:in `initialize'
from /Users/amosng/.rvm/gems/ruby-1.8.7-p370/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/http/common.rb:59:in `new'
from /Users/amosng/.rvm/gems/ruby-1.8.7-p370/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/http/common.rb:59:in `create_response'
from /Users/amosng/.rvm/gems/ruby-1.8.7-p370/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/http/default.rb:65:in `request'
from /Users/amosng/.rvm/gems/ruby-1.8.7-p370/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/http/common.rb:40:in `call'
from /Users/amosng/.rvm/gems/ruby-1.8.7-p370/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/bridge.rb:598:in `raw_execute'
from /Users/amosng/.rvm/gems/ruby-1.8.7-p370/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/bridge.rb:576:in `execute'
from /Users/amosng/.rvm/gems/ruby-1.8.7-p370/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/bridge.rb:542:in `find_element_by'
from /Users/amosng/.rvm/gems/ruby-1.8.7-p370/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/common/search_context.rb:42:in `find_element'
from /Users/amosng/.rvm/gems/ruby-1.8.7-p370/gems/watir-webdriver-0.6.1/lib/watir-webdriver/locators/element_locator.rb:85:in `find_first_by_multiple'
from /Users/amosng/.rvm/gems/ruby-1.8.7-p370/gems/watir-webdriver-0.6.1/lib/watir-webdriver/locators/element_locator.rb:32:in `locate'
from /Users/amosng/.rvm/gems/ruby-1.8.7-p370/gems/watir-webdriver-0.6.1/lib/watir-webdriver/elements/element.rb:384:in `locate'
from /Users/amosng/.rvm/gems/ruby-1.8.7-p370/gems/watir-webdriver-0.6.1/lib/watir-webdriver/elements/element.rb:362:in `assert_exists'
from /Users/amosng/.rvm/gems/ruby-1.8.7-p370/gems/watir-webdriver-0.6.1/lib/watir-webdriver/elements/element.rb:37:in `exists?'
from ./my-script.rb:123:in `foo'
当我只是想知道某个元素是否存在时,有什么可能会引发错误?
编辑:所以似乎将等待时间延长到10秒可以解决问题。由于该页面上有一堆Javascript,我认为在执行form.wait_until_present
时页面可能没有开始重新加载,并且当执行next if form.span(:class => "SSSMSGWARNINGTEXT").exists?
时,表单不再存在于加载页面之间。至少这是我能想到这次事故的唯一原因......
但问题是,我有几个地方重新加载这样的页面。在任何地方添加10秒的睡眠会使其慢慢变成无法忍受的爬行。如何让程序检测页面何时完全重新加载?
编辑2 :每次重页加载时都尝试设置form
:
...
form = browser.form(:name => "win1")
form.wait_until_present
form.a(:id => "CLASS_SRCH_WRK2_SSR_PB_CLASS_SRCH").click
form = browser.form(:name => "win1")
form.wait_until_present
form.input(:id => "#ICSave").click if form.input(:id => "#ICSave").exists?
form = browser.form(:name => "win1")
form.wait_until_present
...
还是一个类似的错误:
[remote server] resource://fxdriver/modules/web_element_cache.js:5665:in `unknown': Element not found in the cache - perhaps the page has changed since it was looked up (Selenium::WebDriver::Error::StaleElementReferenceError)
from [remote server] file:///var/folders/80/_bwll9x91h7d6c5dp2d3fbb00000gr/T/webdriver-profile20120725-47093-y3nzl8/extensions/fxdriver@googlecode.com/components/driver_component.js:5354:in `unknown'
from [remote server] file:///var/folders/80/_bwll9x91h7d6c5dp2d3fbb00000gr/T/webdriver-profile20120725-47093-y3nzl8/extensions/fxdriver@googlecode.com/components/driver_component.js:6597:in `unknown'
from [remote server] file:///var/folders/80/_bwll9x91h7d6c5dp2d3fbb00000gr/T/webdriver-profile20120725-47093-y3nzl8/extensions/fxdriver@googlecode.com/components/driver_component.js:471:in `unknown'
from /Users/amosng/.rvm/gems/ruby-1.9.3-p194/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/response.rb:52:in `assert_ok'
from /Users/amosng/.rvm/gems/ruby-1.9.3-p194/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/response.rb:15:in `initialize'
from /Users/amosng/.rvm/gems/ruby-1.9.3-p194/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/http/common.rb:59:in `new'
from /Users/amosng/.rvm/gems/ruby-1.9.3-p194/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/http/common.rb:59:in `create_response'
from /Users/amosng/.rvm/gems/ruby-1.9.3-p194/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/http/default.rb:65:in `request'
from /Users/amosng/.rvm/gems/ruby-1.9.3-p194/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/http/common.rb:40:in `call'
from /Users/amosng/.rvm/gems/ruby-1.9.3-p194/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/bridge.rb:598:in `raw_execute'
from /Users/amosng/.rvm/gems/ruby-1.9.3-p194/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/bridge.rb:576:in `execute'
from /Users/amosng/.rvm/gems/ruby-1.9.3-p194/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/bridge.rb:542:in `find_element_by'
from /Users/amosng/.rvm/gems/ruby-1.9.3-p194/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/common/search_context.rb:42:in `find_element'
from /Users/amosng/.rvm/gems/ruby-1.9.3-p194/gems/watir-webdriver-0.6.1/lib/watir-webdriver/locators/element_locator.rb:247:in `by_id'
from /Users/amosng/.rvm/gems/ruby-1.9.3-p194/gems/watir-webdriver-0.6.1/lib/watir-webdriver/locators/element_locator.rb:26:in `locate'
from /Users/amosng/.rvm/gems/ruby-1.9.3-p194/gems/watir-webdriver-0.6.1/lib/watir-webdriver/elements/element.rb:384:in `locate'
from /Users/amosng/.rvm/gems/ruby-1.9.3-p194/gems/watir-webdriver-0.6.1/lib/watir-webdriver/elements/element.rb:362:in `assert_exists'
from /Users/amosng/.rvm/gems/ruby-1.9.3-p194/gems/watir-webdriver-0.6.1/lib/watir-webdriver/elements/element.rb:95:in `click'
from my-script.rb:471:in `block (2 levels) in foo'
...
编辑3 :这是完整的测试脚本:
require 'watir-webdriver'
def foo
browser = Watir::Browser.new
browser.driver.manage.timeouts.implicit_wait = 3
browser.goto "http://schedule.arizona.edu"
browser.form(:name => "win1").select_list(:name => "CLASS_SRCH_WRK2_STRM$54$").option(:index => 2).select
browser.goto browser.frame(:name => "TargetContent").src
form = browser.form(:name => "win1")
term_select_list = form.select_list(:name => "CLASS_SRCH_WRK2_STRM$54$")
(1..browser.form(:name => "win1").select_list(:name => "CLASS_SRCH_WRK2_STRM$54$").options.count - 1).each do |term_index|
(1..term_select_list.options.count - 1).each do |subj_index|
term_select_list.option(:index => term_index).select
sleep 1
form.select_list(:name => "CLASS_SRCH_WRK2_SUBJECT$67$").option(:index => subj_index).select
sleep 1
form.checkbox(:id => "CLASS_SRCH_WRK2_SSR_OPEN_ONLY").click
sleep 1
form.a(:id => "CLASS_SRCH_WRK2_SSR_PB_CLASS_SRCH").click
sleep 1
form.input(:id => "#ICSave").click if form.input(:id => "#ICSave").exists?
sleep 10
form.wait_until_present
next if form.span(:class => "SSSMSGWARNINGTEXT").exists?
puts "got the form I want!!! do something with it: #{form.html[0..10]}"
form.a(:id => "CLASS_SRCH_WRK2_SSR_PB_NEW_SEARCH").click
sleep 1
form.wait_until_present
end
end
browser.close
GC.start
end
foo
直到达到ACCT才会崩溃,但是当它到达ACCT时,它会可靠地崩溃(对我而言),尽管这可能只是因为1秒的睡眠时间不够长。
脚本form.wait_until_present
而不是任意睡眠:
require 'watir-webdriver'
def foo
browser = Watir::Browser.new
browser.driver.manage.timeouts.implicit_wait = 3
browser.goto "http://schedule.arizona.edu"
browser.form(:name => "win1").select_list(:name => "CLASS_SRCH_WRK2_STRM$54$").option(:index => 2).select
browser.goto browser.frame(:name => "TargetContent").src
form = browser.form(:name => "win1")
term_select_list = form.select_list(:name => "CLASS_SRCH_WRK2_STRM$54$")
(1..browser.form(:name => "win1").select_list(:name => "CLASS_SRCH_WRK2_STRM$54$").options.count - 1).each do |term_index|
(1..term_select_list.options.count - 1).each do |subj_index|
term_select_list.option(:index => term_index).select
form = browser.form(:name => "win1")
form.wait_until_present
form.select_list(:name => "CLASS_SRCH_WRK2_SUBJECT$67$").option(:index => subj_index).select
form = browser.form(:name => "win1")
form.wait_until_present
form.checkbox(:id => "CLASS_SRCH_WRK2_SSR_OPEN_ONLY").click
form = browser.form(:name => "win1")
form.wait_until_present
form.a(:id => "CLASS_SRCH_WRK2_SSR_PB_CLASS_SRCH").click
form = browser.form(:name => "win1")
form.wait_until_present
form.input(:id => "#ICSave").click if form.input(:id => "#ICSave").exists?
form = browser.form(:name => "win1")
form.wait_until_present
next if form.span(:class => "SSSMSGWARNINGTEXT").exists?
puts "got the form I want!!! do something with it: #{form.html[0..10]}"
form.a(:id => "CLASS_SRCH_WRK2_SSR_PB_NEW_SEARCH").click
form = browser.form(:name => "win1")
form.wait_until_present
end
end
browser.close
GC.start
end
foo
甚至在去ABE之前崩溃。
答案 0 :(得分:3)
有时最好等待某些东西消失,而不是出现什么东西。在这种情况下,当进行ajax调用时,您将获得一个方便的徽标,指出页面正在加载。用以下内容替换所有sleep 1
使脚本完成而没有错误。
browser.image(:id, 'processing').wait_while_present
结果看起来有点奇怪,但以下脚本不再遇到你得到的异常。希望这有助于你至少开始。
require 'watir-webdriver'
def foo
browser = Watir::Browser.new
browser.driver.manage.timeouts.implicit_wait = 3
browser.goto "http://schedule.arizona.edu"
browser.form(:name => "win1").select_list(:name => "CLASS_SRCH_WRK2_STRM$54$").option(:index => 2).select
browser.goto browser.frame(:name => "TargetContent").src
form = browser.form(:name => "win1")
term_select_list = form.select_list(:name => "CLASS_SRCH_WRK2_STRM$54$")
(1..browser.form(:name => "win1").select_list(:name => "CLASS_SRCH_WRK2_STRM$54$").options.count - 1).each do |term_index|
(1..term_select_list.options.count - 1).each do |subj_index|
term_select_list.option(:index => term_index).select
browser.image(:id, 'processing').wait_while_present
form.select_list(:name => "CLASS_SRCH_WRK2_SUBJECT$67$").option(:index => subj_index).select
browser.image(:id, 'processing').wait_while_present
form.checkbox(:id => "CLASS_SRCH_WRK2_SSR_OPEN_ONLY").click
browser.image(:id, 'processing').wait_while_present
form.a(:id => "CLASS_SRCH_WRK2_SSR_PB_CLASS_SRCH").click
browser.image(:id, 'processing').wait_while_present
form.input(:id => "#ICSave").click if form.input(:id => "#ICSave").exists?
browser.image(:id, 'processing').wait_while_present
form.wait_until_present
next if form.span(:class => "SSSMSGWARNINGTEXT").exists?
puts "got the form I want!!! do something with it: #{form.html[0..10]}"
form.a(:id => "CLASS_SRCH_WRK2_SSR_PB_NEW_SEARCH").click
browser.image(:id, 'processing').wait_while_present
form.wait_until_present
end
end
browser.close
GC.start
end
foo