【问题标题】:Q: about implicit waits in python + selenium问:关于 python + selenium 中的隐式等待
【发布时间】:2017-04-29 17:56:07
【问题描述】:

我有一个关于隐式等待在 selenium 中的工作方式的问题。据我了解,隐式等待等到元素被定位/可见/存在,并具有给定的最大值。例如:

wait = WebDriverWait(driver, 
10).until(EC.presence_of_element_located((By.CLASSNAME,'classname')))

这个语句让 selenium 等待,直到找到具有类名 'classname' 的元素,或者直到满足最长十秒的等待时间,对吧?

现在,我编写了一个从网站获取数据并使用隐式等待的脚本,如下所示:

def move_to_next_page():
    (this function loads the next page)

def get_page_data():
    wait = WebDriverWait(driver, 
    10).until(EC.presence_of_element_located((By.CLASS_NAME, 'class')))
    items = driver.find_elements_by_class_name('class')
    for item in items:
        itemList.append(item.text)
    return itemList

move_to_next_page()
get_page_data()

昨天,我成功运行了这个脚本几次;隐式等待使我的程序暂停了长达五秒钟,以确保一切正常。但是,我现在正在尝试运行脚本,大约 70% 的时间我收到一条错误消息:

selenium.common.exceptions.StaleElementReferenceException: Message: 
stale element reference: element is not attached to the page document 

暗示浏览器仍在加载?奇怪的是,我在达到 10 秒的限制之前收到了这条消息。我什至尝试了 20 和 30 秒,但 selenium 仍然崩溃了很多次。为什么 selenium 不会等待至少 10/20/30 秒?

我很确定隐式等待会导致崩溃,因为当我使用显式等待时:

time.sleep(4)

程序每次都运行。

我有我正在寻找的数据,所以我不再需要这个脚本了。只是不能写出不管浏览器加载时间如何都能正常工作的东西,这真的很令人沮丧。

【问题讨论】:

  • 您的意思是显式等待 (WebDriverWait + ExpectedConditions) 还是隐式等待 (webdriver.implicitly_wait())?
  • WebDriverWait + ExpectedConditions!

标签: python selenium webdriver wait


【解决方案1】:

首先,WebDriverWaitExpectedConditions 是显式等待,而不是隐式等待。您可以了解更多关于 here 的区别,但长话短说 explicit wait 正在等待满足特定条件,implicit wait 正在等待元素存在于 DOM 中。

至于例外,StaleElementReferenceException 并不意味着页面没有加载,它意味着 DOM 在您找到该元素的时间和您尝试对其进行操作的时间之间发生了更改或重新加载。您可以在错误消息中看到它

过时的元素引用:元素未附加到页面文档

你可以试试presence_of_all_elements_located

items = WebDriverWait(driver, 10).until(EC.presence_of_all_elements_located((By.CLASS_NAME, 'class')))
for item in items:
    itemList.append(item.text)

WebDriverWait.until 将返回 ExpectedConditions 正在检查的元素。

【讨论】:

  • 感谢您的回复!另一个简单的问题:dom什么时候改变?单击“下一页”后或新页面完全加载后?
  • @titusAdam 点击“下一页”肯定会改变 DOM。在某些网站中,可能会有 JavaScript 进程在页面加载后继续更改页面,
  • @titusAdam 如果不使用该站点,我无法确定,但 JavaScript 进程可能正在更改满足的站点,有时在满足条件之前,有时在满足条件之后。这就是为什么它在某些时候起作用的原因。 time.sleep(3) 给了这个过程足够的时间来完成。
【解决方案2】:

我写了一个通用的方法来解决 selenium 中的等待问题,我已经测试过了,它工作正常。

timeout = 是你想要给出的总超时时间

value = 是标识符

key = 发送键值。如果要点击,请留空

input = "C" = 点击 "S" = sendkey

def wait_and_send( timeout,value,key,byWhat="By.ID",input=""):

       try:
            el = WebDriverWait(browser,time).until(
            EC.presence_of_element_located((eval(byWhat),value))
            )
            if input == "C":
                el.click()
            if input == "S":
                el.send_keys(key)
        except:
            print EC.NoSuchElementException

例如。 wait_and_send(10,"identifier","abc@test.com","By.NAME","S")

【讨论】:

    猜你喜欢
    • 2020-05-07
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 2014-05-07
    • 2022-06-22
    • 1970-01-01
    • 2012-12-08
    相关资源
    最近更新 更多