selenium 如何在不刷新DOM的情况下使用Python中的Selify更新多个页面元素,以避免StaleElementReferenceException异常?

fdx2calv  于 2022-11-10  发布在  Python
关注(0)|答案(1)|浏览(152)

我有一个学校网站的html页面,用来发布作业,看起来像这样:

当你点击每一课时,会弹出一个javascript div元素,你在作业中写下并通过一个按钮提交。我想自动填充整个表。问题是,每次提交作业条目(通过http post)后,DOM都会刷新。尝试更新下一个条目显然会失败,并抛出以下异常:
Selenium.common.exceptions.StaleElementReferenceException:消息:的元素引用(描述的元素)已过时;元素不再附加到DOM,不在当前框架上下文中,或者文档已刷新。
我像这样循环所有的课程:

monthly_classes = driver.find_elements(By.XPATH, '//div[@class="homework_entry"]')
count = 0
for item in monthly_classes:
    if item.text == "Lesson 1":
        item.click()
        postHomework()
        count += 1
        print(item)
    else:
        print("Pass")

在提交后,我尝试使用以下代码阻止重新加载DOM:

driver.execute_script("window.stop();")

driver.find_element(By.TAG_NAME, "body").send_keys("Keys.ESCAPE")

有什么方法可以防止DOM重新加载吗?有没有更好的方法来尝试完成这项任务?

ifsvaxew

ifsvaxew1#

每次Selify找到元素时,它都会为其创建一个标识符。因此,当您在该页面上提交某些内容时,页面会重新加载,并且所有元素对于Selify来说都是新的(它们现在有了其他标识符)。
要解决此问题,您需要在提交后重新查找所有元素。
所以首先,你需要知道元素的数量。然后,您可以开始按索引遍历它们。在循环的末尾,再次找到元素:

monthly_classes = driver.find_elements(By.XPATH, '//div[@class="homework_entry"]')
monthly_classes_count = len(monthly_classes)

for i in range(monthly_classes_count):
    if monthly_classes[i].text == "Lesson 1":
        monthly_classes[i].click()
        postHomework()
        count += 1
        print(item)
    else:
        print("Pass")
    monthly_classes = driver.find_elements(By.XPATH, '//div[@class="homework_entry"]')

相关问题