硒隐式等待不起作用
selenium implicitly wait doesn't work
这是我第一次使用 selenium 和无头浏览器,因为我想使用 ajax 技术抓取一些网页。
效果很好,但有些情况下加载整个页面会花费太多时间(尤其是当某些资源不可用时),所以我必须为selenium设置一个超时时间。
首先我尝试了set_page_load_timeout()
和set_script_timeout()
,但是当我设置这些超时时,如果页面没有完全加载我将得不到任何页面源代码,如下面的代码:
driver = webdriver.Chrome(chrome_options=options)
driver.set_page_load_timeout(5)
driver.set_script_timeout(5)
try:
driver.get(url)
except Exception:
driver.execute_script('window.stop()')
print driver.page_source.encode('utf-8') # raise TimeoutException this line.
所以我尝试使用隐式等待和条件等待,如下所示:
driver = webdriver.Firefox(firefox_options=options, executable_path=path)
print("Firefox Headless Browser Invoked")
wait = WebDriverWait(driver, timeout=10)
driver.implicitly_wait(2)
start = time.time()
driver.get(url)
end = time.time()
print 'time used: %s s' % str(end - start)
try:
WebDriverWait(driver, 2, 0.5).until(expected.presence_of_element_located((By.TAG_NAME, 'body')))
print driver.find_element_by_tag_name('body').text
except Exception:
driver.execute_script('window.stop()')
这次我得到我want.However的内容,它需要很长时间(40+秒),这意味着我设置的超时2秒根本不起作用。
在我看来,似乎 driver.get()
调用在浏览器停止加载页面之前结束,只有在那之后下面的代码才能工作,并且您无法终止 get()
调用或你什么也得不到。
但这与 selenium 文档非常不同,我真的想知道错误在哪里。
环境:OSX 10.12,selenium 3.0.9 with FireFox & GoogleChrome Headless(均为最新版本。)
---更新----
感谢help.I修改代码如下,单独使用WebDriverWait()
,但仍然存在调用持续很长时间的情况,远远超过我设置的超时时间。
不知道我是否可以在时间结束时立即停止页面加载?
driver = webdriver.Firefox(firefox_options=options, executable_path=path)
print("Firefox Headless Browser Invoked")
start = time.time()
driver.get('url')
end = time.time()
print 'time used: %s s' % str(end - start)
try:
WebDriverWait(driver, 2, 0.5).until(expected.presence_of_element_located((By.TAG_NAME, 'body')))
print driver.find_element_by_tag_name('body').text
except Exception:
driver.execute_script('window.stop()')
driver.quit()
这是测试中的终端输出:
Firefox Headless Browser Invoked
time used: 44.6049938202 s
根据代码,这意味着 driver.get()
调用需要 44 秒才能完成调用,这是意外的,我想知道我是否误解了无头浏览器的行为?
正如您在问题中提到的那样 加载整个页面需要太多时间(尤其是当某些资源不可用时) 如果 正在测试的应用程序 (AUT) 使用JavaScript 或AJAX 调用.
- 在您的第一个场景中,您同时引入了
set_page_load_timeout(5)
和 set_script_timeout(5)
set_page_load_timeout(time_to_wait)
: 设置在抛出异常之前等待页面加载完成的时间。
set_script_timeout(time_to_wait)
:设置脚本在 execute_async_script
调用期间抛出异常之前应等待的时间。
因此 被测应用程序 依赖于 JavaScript 或 AJAX 调用 在两个条件都存在的情况下引发 TimeoutException.
在你的第二种情况下,你已经诱导了 implicitly_wait(2)
和 WebDriverWait(driver, 2, 0.5)
。
implicitly_wait(time_to_wait)
:设置超时以隐式等待找到元素或完成命令。
WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)
: Sets the timeout in-conjunction with different expected_conditions
- 但是您正在经历很长的超时(40 秒以上) 正如 docs 中明确提到的那样不要混合隐式和显式等待可能导致不可预测的等待时间
WARNING : Do not mix implicit and explicit waits. Doing so can cause unpredictable wait times. For example setting an implicit wait of 10 seconds and an explicit wait of 15 seconds, could cause a timeout to occur after 20 seconds.
解决方案:
最好的解决方案是删除 implicitly_wait(time_to_wait)
的所有实例并替换为 WebDriverWait()
以获得 被测应用程序 (AUT)[=97= 的稳定行为].
更新
根据您的反问,当前代码块看起来很完美。您所看到的 time used: 44.6049938202 s
的时间度量是 网页 完全和正常加载所需的时间,即 客户端所需的时间(即 Web 浏览器)到 return 将控件返回给 WebDriver 实例一次 'document.readyState'等于"complete"就实现了。 Selenium 或者作为用户,您无法控制此渲染过程。但是,为了获得更好的性能,您可以遵循以下最佳做法:
- 保持您的 JDK 版本当前更新 Java SE Development Kit 8u162
- 保持您的 Selenium Client 版本当前更新 selenium 3.9.0
- 保持您的 WebDriver 版本更新。
- 保持您的 Web 浏览器 版本更新。
- 定期清理 Project Workspace 中的 IDE 以仅使用所需的依赖项构建项目。
- 使用 CCleaner 工具清除 OS 执行 测试套件 前后的琐事。
- 如果您的 Web 浏览器 基础版本太旧,请通过 Revo Uninstaller 卸载 Web 浏览器 并安装最近发布的 GA Web 浏览器的版本。
- 执行你的测试。
这是我第一次使用 selenium 和无头浏览器,因为我想使用 ajax 技术抓取一些网页。
效果很好,但有些情况下加载整个页面会花费太多时间(尤其是当某些资源不可用时),所以我必须为selenium设置一个超时时间。
首先我尝试了set_page_load_timeout()
和set_script_timeout()
,但是当我设置这些超时时,如果页面没有完全加载我将得不到任何页面源代码,如下面的代码:
driver = webdriver.Chrome(chrome_options=options)
driver.set_page_load_timeout(5)
driver.set_script_timeout(5)
try:
driver.get(url)
except Exception:
driver.execute_script('window.stop()')
print driver.page_source.encode('utf-8') # raise TimeoutException this line.
所以我尝试使用隐式等待和条件等待,如下所示:
driver = webdriver.Firefox(firefox_options=options, executable_path=path)
print("Firefox Headless Browser Invoked")
wait = WebDriverWait(driver, timeout=10)
driver.implicitly_wait(2)
start = time.time()
driver.get(url)
end = time.time()
print 'time used: %s s' % str(end - start)
try:
WebDriverWait(driver, 2, 0.5).until(expected.presence_of_element_located((By.TAG_NAME, 'body')))
print driver.find_element_by_tag_name('body').text
except Exception:
driver.execute_script('window.stop()')
这次我得到我want.However的内容,它需要很长时间(40+秒),这意味着我设置的超时2秒根本不起作用。
在我看来,似乎 driver.get()
调用在浏览器停止加载页面之前结束,只有在那之后下面的代码才能工作,并且您无法终止 get()
调用或你什么也得不到。
但这与 selenium 文档非常不同,我真的想知道错误在哪里。
环境:OSX 10.12,selenium 3.0.9 with FireFox & GoogleChrome Headless(均为最新版本。)
---更新----
感谢help.I修改代码如下,单独使用WebDriverWait()
,但仍然存在调用持续很长时间的情况,远远超过我设置的超时时间。
不知道我是否可以在时间结束时立即停止页面加载?
driver = webdriver.Firefox(firefox_options=options, executable_path=path)
print("Firefox Headless Browser Invoked")
start = time.time()
driver.get('url')
end = time.time()
print 'time used: %s s' % str(end - start)
try:
WebDriverWait(driver, 2, 0.5).until(expected.presence_of_element_located((By.TAG_NAME, 'body')))
print driver.find_element_by_tag_name('body').text
except Exception:
driver.execute_script('window.stop()')
driver.quit()
这是测试中的终端输出:
Firefox Headless Browser Invoked
time used: 44.6049938202 s
根据代码,这意味着 driver.get()
调用需要 44 秒才能完成调用,这是意外的,我想知道我是否误解了无头浏览器的行为?
正如您在问题中提到的那样 加载整个页面需要太多时间(尤其是当某些资源不可用时) 如果 正在测试的应用程序 (AUT) 使用JavaScript 或AJAX 调用.
- 在您的第一个场景中,您同时引入了
set_page_load_timeout(5)
和set_script_timeout(5)
set_page_load_timeout(time_to_wait)
: 设置在抛出异常之前等待页面加载完成的时间。set_script_timeout(time_to_wait)
:设置脚本在execute_async_script
调用期间抛出异常之前应等待的时间。
因此 被测应用程序 依赖于 JavaScript 或 AJAX 调用 在两个条件都存在的情况下引发 TimeoutException.
在你的第二种情况下,你已经诱导了
implicitly_wait(2)
和WebDriverWait(driver, 2, 0.5)
。implicitly_wait(time_to_wait)
:设置超时以隐式等待找到元素或完成命令。WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)
: Sets the timeout in-conjunction with differentexpected_conditions
- 但是您正在经历很长的超时(40 秒以上) 正如 docs 中明确提到的那样不要混合隐式和显式等待可能导致不可预测的等待时间
WARNING : Do not mix implicit and explicit waits. Doing so can cause unpredictable wait times. For example setting an implicit wait of 10 seconds and an explicit wait of 15 seconds, could cause a timeout to occur after 20 seconds.
解决方案:
最好的解决方案是删除 implicitly_wait(time_to_wait)
的所有实例并替换为 WebDriverWait()
以获得 被测应用程序 (AUT)[=97= 的稳定行为].
更新
根据您的反问,当前代码块看起来很完美。您所看到的 time used: 44.6049938202 s
的时间度量是 网页 完全和正常加载所需的时间,即 客户端所需的时间(即 Web 浏览器)到 return 将控件返回给 WebDriver 实例一次 'document.readyState'等于"complete"就实现了。 Selenium 或者作为用户,您无法控制此渲染过程。但是,为了获得更好的性能,您可以遵循以下最佳做法:
- 保持您的 JDK 版本当前更新 Java SE Development Kit 8u162
- 保持您的 Selenium Client 版本当前更新 selenium 3.9.0
- 保持您的 WebDriver 版本更新。
- 保持您的 Web 浏览器 版本更新。
- 定期清理 Project Workspace 中的 IDE 以仅使用所需的依赖项构建项目。
- 使用 CCleaner 工具清除 OS 执行 测试套件 前后的琐事。
- 如果您的 Web 浏览器 基础版本太旧,请通过 Revo Uninstaller 卸载 Web 浏览器 并安装最近发布的 GA Web 浏览器的版本。
- 执行你的测试。