【问题标题】:Is it necessary to set waiting time while working with Selenium?使用 Selenium 时是否需要设置等待时间?
【发布时间】:2019-10-19 20:38:26
【问题描述】:

有人说需要设置等待时间,否则可能会因为页面没有完成加载而导致NoSuchElementException错误。

但是,我在低速网络(我限制了速度)下尝试了以下代码(没有任何等待线),登录过程仍然运行顺利(一开始一直在加载,当我取消限制时,加载立即完成,事情继续......)。

from selenium import webdriver
import json

# Get user info
with open('wjxlogin.json', encoding='utf-8') as fp_login:
    login = json.load(fp_login)
username = login['username']
password = login['password']

# First login
browser = webdriver.Firefox()
browser.get('https://www.wjx.cn/login.aspx')
browser.find_element_by_id('UserName').send_keys(username)
browser.find_element_by_id('Password').send_keys(password)
browser.find_element_by_id('RememberMe').click()
browser.find_element_by_id('LoginButton').click()

所以,我想知道当前 Selenium 中是否有自动等待模式,在最后一个进程完成之前不允许执行下一行? 是否仍然需要设置等待时间(例如在我的代码中)?

【问题讨论】:

  • 动态加载内容时

标签: python selenium css-selectors webdriverwait nosuchelementexception


【解决方案1】:

Selenium 中的默认超时设置为 0。这意味着Selenium 将在页面完成加载并且特定元素不存在于DOM 后抛出NoSuchElementExpception。默认的 页面 加载超时非常高(我认为它是 600 秒) - 这就是为什么您在网络不好的情况下所做的尝试不会影响测试执行。

但是 - 更改页面加载超时不会导致 NoSuchElementException 而是会引发不同的异常。如果您想尝试这些设置:

driver.set_page_load_timeout(3)

可能会让您在网络速度有限的情况下出现一些故障。

说到等待——正如你所见,你并不需要它。仅在某些特定情况下才需要 - 即更新动态内容、用户交互加载某些元素等。

【讨论】:

  • 另外值得注意的是,一些动态内容将使用触发 onload 的书签更新位置栏。使用此方法的站点可能不需要 webdriverwait。 (这是一种可能已经过时的技术,但允许添加书签和适当的前进后退按钮功能。) hashchange 事件触发动态加载。
【解决方案2】:

根据最佳实践,您需要设置一个等待时间,即WebDriverWait 形式的waiterexpected_conditions 中的任何一个一起使用使用Selenium时。

您可以在以下位置找到相关的详细讨论:


这个用例

根据您使用一组有效凭据在website 内登录的用例,您可以使用以下解决方案:

  • 代码块:

    from selenium import webdriver
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC 
    
    options = webdriver.ChromeOptions() 
    driver = webdriver.Chrome(options=options, executable_path=r'C:\Utility\BrowserDrivers\chromedriver.exe')
    driver.get("https://www.wjx.cn/login.aspx")
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input.validate-input.user-name#UserName"))).send_keys("TheCoolestStacker")
    driver.find_element_by_css_selector("input#Password[name='Password']").send_keys("TheCoolestStacker")
    driver.find_element_by_css_selector("input#RememberMe[name='RememberMe']").click()
    driver.find_element_by_css_selector("input.submitbutton#LoginButton").click()
    
  • 浏览器快照:


NoSuchElementException

您可以在以下位置找到关于 NoSuchElementException 的一些详细讨论:

【讨论】:

  • 谢谢!你知道为什么在我的情况下没有发生错误吗?在加载成功或到达错误页面之前,似乎“find_element ...”行不会执行。这就是为什么我怀疑添加“等待”的必要性。
  • @TheCoolestStacker loading is successfulSelenium 的 角度来看,这个词非常主观。当您开始与动态元素进行交互时,find_element_by_*Implicitly Wait 结合使用在更大范围内不会那么有效。因此,更好的方法是我在回答中谈到的 WebDriverWait
  • 如果在初始页面加载后没有发送额外的请求,那么您不需要等待。所以它并不总是需要
猜你喜欢
  • 2016-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-27
相关资源
最近更新 更多