问:关于python + selenium中的隐式等待

时间:2016-12-14 11:54:24

标签: python selenium webdriver wait

我对隐含等待在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秒,但硒仍然会很多次崩溃。为什么硒不会等待至少10/20/30秒?

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

time.sleep(4)

程序每次都会运行。

我有我正在寻找的数据,所以我不再需要这个脚本了。只是因为无论浏览器的加载时间如何,都无法编写能够正常工作的内容,这真是令人沮丧。

提前致谢!

2 个答案:

答案 0 :(得分: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正在检查的元素。

答案 1 :(得分:1)

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

timeout =是您要提供的总超时

value =是标识符

key =发送密钥值。如果要单击

,请将其留空

输入=" 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

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