Selenium Python中存在StaleElementException错误



我正在从事一个web自动化项目。这个项目是我个人的,因为我必须不断点击并填写网络应用程序(IBM Maximo Asset Management(上的文本字段。登录,然后单击我想去的链接最初工作得很好,但当我开始单击每一新行上的文本字段时,我会出现错误。就好像添加一个新行会改变整个DOM,但它只会在DOM中创建另一个表,而其他表则保持不变。如果可能的话,我很想有一个合作者帮我解决这个问题。

你会看到,在一些地方,由于自动化刚刚中断,我不得不使用完整的XPATH,例如:

if driver.find_element(
                By.XPATH,
                "/html/body/form/div/table[2]/tbody/tr/td/table/tbody/tr/td/table/tbody/tr/td/table/tbody/tr[2]/td/div/table/tbody/tr/td/div/table/tbody/tr/td/table/tbody/tr/td/div/table/tbody/tr/td/table/tbody/tr[2]/td/table/tbody/tr[2]/td/div/table/tbody/tr[3]/td/table/tbody/tr[3]/td/table/tbody/tr[4]/td[10]").text == "WSCH":

如果没有完整的XPATH,代码就找不到这个元素。那么,我应该为所有元素使用完整的XPATH进行编码吗?请提出建议。

我觉得我应该为整个代码做这件事,但如果网络应用程序被更改或更新,这将使更改变得非常困难。

这是我的全部代码。

import datetime
import time
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException, StaleElementReferenceException
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.ui import WebDriverWait
# from selenium.webdriver.common.action_chains import ActionChains
options = webdriver.ChromeOptions()
prefs = {"download.default_directory": "C:\Users\Administrator\Desktop\NewWO\NEW"}
options.add_experimental_option("prefs", prefs)
PATH = "C:\Users\Administrator\Desktop\chromedriver_win32\chromedriver.exe"
driver = webdriver.Chrome(PATH, options=options)
# Wait 3 seconds for the "chromedriver.exe" to load
time.sleep(3)
action = ActionChains(driver)
# Open IBM MAXIMO Asset Management Web App
driver.get("http://10.1.84.87/maximo/webclient/login/login.jsp?appservauth=true")
driver.maximize_window()
# Wait 2 seconds for login elements to load
time.sleep(4)
# Login to IBM Maximo Asset Management
# Pass login parameters
with open("C:\Users\Administrator\Desktop\WO_Automation\pass.txt", "r") as p:
    maximo_pass_supervisor = p.read()
id_box = driver.find_element(By.ID, 'j_username')
id_box.send_keys("07780141")
pass_box = driver.find_element(By.ID, 'j_password')
pass_box.send_keys(maximo_pass_supervisor)
pass_box.submit()
# Click on "Work Order Tracking" link after login
element_wo_tracking = WebDriverWait(driver, 600).until(
    ec.visibility_of_element_located((By.LINK_TEXT, "Work Order Tracking")))
wo_track = driver.find_element(By.LINK_TEXT, "Work Order Tracking")
wo_track.click()
time.sleep(3)
# Create a list of arguments to be entered into fields based on the 'description.txt' file
pm_actuals = []
with open("C:\Users\Administrator\Desktop\PM.txt", "r") as pm_number:
    pm = pm_number.readlines()[11:12]
    for line in pm:
        line = line.upper().strip().split(",")
        pm_actuals.append(line)

# A function to send text to an element one character at a time with a delay of 0.1s
def slow_type(el, text, delay=0.1):
    for character in text:
        el.send_keys(character)
        time.sleep(delay)

# Check for PM availability
pm_availability = []
for pm in range(0, len(pm_actuals[0])):
    time.sleep(1)
    ignore_exceptions = (NoSuchElementException, StaleElementReferenceException,)
    element_search_text_wo = WebDriverWait(driver, 120, 5, ignore_exceptions).until(
        ec.element_to_be_clickable((By.XPATH, "//input[@id='m6a7dfd2f_tfrow_[C:1]_txt-tb']")))
    search_text_wo = driver.find_element(By.XPATH, "//input[@id='m6a7dfd2f_tfrow_[C:1]_txt-tb']")
    search_text_wo.clear()
    slow_type(search_text_wo, pm_actuals[0][pm].replace(" ", "", 1))
    search_text_wo.send_keys(Keys.RETURN)
    element_len_elements_list = WebDriverWait(driver, 120, 5, ignore_exceptions).until(
        ec.visibility_of_any_elements_located((By.XPATH, "//*[contains(@id, 'm6a7dfd2f_tbod_tdrow-tr[R:')]")))
    len_elements_list = driver.find_elements(By.XPATH, "//*[contains(@id, 'm6a7dfd2f_tbod_tdrow-tr[R:')]")
    if len(len_elements_list) != 0:
        # Check if PM status is WSCH
        if driver.find_element(
                By.XPATH,
                "/html/body/form/div/table[2]/tbody/tr/td/table/tbody/tr/td/table/tbody/tr/td/table/tbody/tr[2]/td/div/table/tbody/tr/td/div/table/tbody/tr/td/table/tbody/tr/td/div/table/tbody/tr/td/table/tbody/tr[2]/td/table/tbody/tr[2]/td/div/table/tbody/tr[3]/td/table/tbody/tr[3]/td/table/tbody/tr[4]/td[10]").text == "WSCH":
            pm_availability.append(pm_actuals[0][pm].replace(" ", "", 1))
            continue
        # If PM status is not WSCH, continue searching
        else:
            continue
    else:
        continue
# Exceptions to ignore
ignore_exceptions = (NoSuchElementException, StaleElementReferenceException,)
# Start PM routing
counter = 0
while len(pm_availability) != 0:
    for i in range(0, len(pm_availability)):
        element_search_text_wo = WebDriverWait(driver, 120, 5, ignore_exceptions).until(
            ec.element_to_be_clickable((By.XPATH, "//input[@id='m6a7dfd2f_tfrow_[C:1]_txt-tb']")))
        search_text_wo = driver.find_element(By.XPATH, "//input[@id='m6a7dfd2f_tfrow_[C:1]_txt-tb']")
        search_text_wo.clear()
        slow_type(search_text_wo, pm_availability[i])
        search_text_wo.send_keys(Keys.RETURN)
        # Start PM routing procedure if the status is WSCH
        # Select the PM
        element_first_row_search = WebDriverWait(driver, 600, 5, ignore_exceptions).until(
            ec.presence_of_element_located(
                (By.XPATH,
                 "/html/body/form/div/table[2]/tbody/tr/td/table/tbody/tr/td/table/tbody/tr/td/table/tbody/tr[2]/td/div/table/tbody/tr/td/div/table/tbody/tr/td/table/tbody/tr/td/div/table/tbody/tr/td/table/tbody/tr[2]/td/table/tbody/tr[2]/td/div/table/tbody/tr[3]/td/table/tbody/tr[3]/td/table/tbody/tr[4]/td[3]/span[@id='m6a7dfd2f_tdrow_[C:1]_ttxt-lb[R:0]']")))
        first_row = driver.find_element(
            By.XPATH, "/html/body/form/div/table[2]/tbody/tr/td/table/tbody/tr/td/table/tbody/tr/td/table/tbody/tr[2]/td/div/table/tbody/tr/td/div/table/tbody/tr/td/table/tbody/tr/td/div/table/tbody/tr/td/table/tbody/tr[2]/td/table/tbody/tr[2]/td/div/table/tbody/tr[3]/td/table/tbody/tr[3]/td/table/tbody/tr[4]/td[3]/span[@id='m6a7dfd2f_tdrow_[C:1]_ttxt-lb[R:0]']")
        first_row.click()
        time.sleep(3)
        # Go to ACTUALS tab
        element_actuals_tab = WebDriverWait(driver, 120, 5, ignore_exceptions).until(
            ec.element_to_be_clickable((By.XPATH, "//*[@id='m272f5640-tab']")))
        actuals_tab = driver.find_element(By.XPATH, "//*[@id='m272f5640-tab']")
        actuals_tab.click()
        # Create a list of all labor information
        pm_labor = []
        with open("C:\Users\Administrator\Desktop\PM.txt", "r") as pm_info:
            pm = pm_info.readlines()[14:]
            for line in pm:
                line = line.upper().strip().split(",")
                pm_labor.append(line)
        # Create a list of duration to calculate the PM start and end times
        duration = []
        with open("C:\Users\Administrator\Desktop\PM.txt", "r") as pm_duration:
            pm = pm_duration.readlines()[8:9]
            for line in pm:
                line = line.upper().strip().split(".")
                duration.append(line)
        # Create a list for the start_time_pm values
        starting_time = []
        with open("C:\Users\Administrator\Desktop\PM.txt", "r") as pm_start:
            start = pm_start.readlines()[3:5]
            for line in start:
                line = line.upper().strip().split("=")
                starting_time.append(line)
        # Start time for all PMs will be 0700 hours
        start_time_pm = datetime.timedelta(hours=int(starting_time[0][1]),
                                           minutes=int(starting_time[1][1]), seconds=0)
        # Create a list of times based on the duration of PM in PM.txt file
        start_time = []
        end_time = []
        # Iterate the time starting from 0700 hours to create PM time slots
        while start_time_pm < datetime.timedelta(hours=14, minutes=0):
            end_time_pm = start_time_pm + datetime.timedelta(hours=int(duration[0][0])) + 
                          datetime.timedelta(minutes=int(duration[0][1]))
            # If end time is 1415 hours or less, append the time values to the lists
            if end_time_pm <= datetime.timedelta(hours=14, minutes=15):
                start_time.append(str(start_time_pm))
                end_time.append(str(end_time_pm))
                start_time_pm = start_time_pm + datetime.timedelta(hours=int(duration[0][0])) + 
                                datetime.timedelta(minutes=int(duration[0][1])) + 
                                datetime.timedelta(minutes=15)
            # If end time is 1400 hours or more, break out of the loop
            elif end_time_pm >= datetime.timedelta(hours=14, minutes=0):
                break
            else:
                continue
        time.sleep(2)
        # Add labor information
        for labor_row in range(0, len(pm_labor)):
            try:
                # Click on new labor for a new row to enter labor information
                element_new_labor = WebDriverWait(driver, 60, 5, ignore_exceptions).until(
                    ec.element_to_be_clickable((By.XPATH, "//*[@id='m4dfd8aef_bg_button_addrow-pb']")))
                new_labor = driver.find_element(By.XPATH, "//*[@id='m4dfd8aef_bg_button_addrow-pb']")
                new_labor.click()
                time.sleep(2)
                # Add labor ID from pm_labour list
                element_labor_id = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
                    ec.element_to_be_clickable((
                        By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:2]_txt-tb[R:" + str(labor_row) + "]']")))
                labor_id = driver.find_element(
                    By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:2]_txt-tb[R:" + str(labor_row) + "]']")
                labor_id.clear()
                slow_type(labor_id, pm_labor[labor_row][0].replace(" ", "", 1))
                time.sleep(2)
                # Add start date for PM from pm_labour list
                element_start_date = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
                    ec.element_to_be_clickable((
                        By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:6]_txt-tb[R:" + str(labor_row) + "]']")))
                start_date = driver.find_element(
                    By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:6]_txt-tb[R:" + str(labor_row) + "]']")
                start_date.clear()
                slow_type(start_date, pm_labor[labor_row][1].replace(" ", "", 1))
                time.sleep(2)
                # Add end date for PM from pm_labour list
                element_end_date = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
                    ec.element_to_be_clickable((
                        By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:7]_txt-tb[R:" + str(labor_row) + "]']")))
                end_date = driver.find_element(
                    By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:7]_txt-tb[R:" + str(labor_row) + "]']")
                end_date.clear()
                slow_type(end_date, pm_labor[labor_row][1].replace(" ", "", 1))
                time.sleep(2)
                # Add start time for PM from start_time list
                element_start_time = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
                    ec.element_to_be_clickable(
                        (By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:8]_txt-tb[R:" + str(labor_row) + "]']")))
                start_time_text = driver.find_element(
                    By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:8]_txt-tb[R:" + str(labor_row) + "]']")
                start_time_text.clear()
                slow_type(start_time_text, start_time[counter])
                time.sleep(2)
                # Add end time for PM from end_time list
                element_end_time = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
                    ec.element_to_be_clickable(
                        (By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:9]_txt-tb[R:" + str(labor_row) + "]']")))
                end_time_text = driver.find_element(
                    By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:9]_txt-tb[R:" + str(labor_row) + "]']")
                end_time_text.clear()
                slow_type(end_time_text, end_time[counter])
                time.sleep(3)
            except StaleElementReferenceException:
                # Delete row if exception is thrown and continue with loop
                element_delete_row = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
                    ec.element_to_be_clickable(
                        (By.XPATH,
                         "//*[@id='m900f2d81_tdrow_[C:9]_toggleimage-ti[R:" + str(labor_row) + "]']")))
                driver.find_element(
                    By.XPATH,
                    "//*[@id='m900f2d81_tdrow_[C:9]_toggleimage-ti[R:" + str(labor_row) + "]']").click()
                if labor_row == 0:
                    labor_row = 0
                    continue
                else:
                    labor_row += 0
                    continue
        # If labor rows are filled, then route the PM work order
        for rout in range(0, 3):
            if driver.find_element(By.XPATH, "//*[@id='md489b5d4-tb']").text != "COMP":
                # Click on the route button
                element_route = WebDriverWait(driver, 180, 20, ignore_exceptions).until(
                    ec.element_to_be_clickable((By.XPATH, "//*[@id='ROUTEWF_KAUWO_-tbb_anchor']")))
                route = driver.find_element(By.XPATH, "//*[@id='ROUTEWF_KAUWO_-tbb_anchor']")
                route.click()
                time.sleep(5)
                # Click on OK in the corresponding dialog box
                # element_click_ok = WebDriverWait(driver, 180, 20, ignore_exceptions).until(
                #     ec.element_to_be_clickable((By.XPATH, "//button[@type='button' and @id='md875c1f9-pb']")))
                #
                # click_ok = driver.find_element(By.XPATH, "//button[@type='button' and @id='md875c1f9-pb']")
                #
                # click_ok.click()
                driver.switch_to.alert.accept()
                time.sleep(5)
            else:
                pass
        # Once the PM work order is routed, go back to search field
        element_list_view = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
            ec.visibility_of_element_located((By.XPATH,
                                              "//*[@id='m397b0593-tabs_backToList']/table/tbody/tr/td[1]")))
        list_view = driver.find_element(By.XPATH,
                                        "//*[@id='m397b0593-tabs_backToList']/table/tbody/tr/td[1]")
        time.sleep(2)
        list_view.click()
        time.sleep(2)
        pms_routed = [print(f"WO {pm_actuals[0][i]} is closed.")]
        counter += 1
        time.sleep(2)
        len(pm_availability) - 1
# Log out and quit
element_logout = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
    ec.element_to_be_clickable((
        By.XPATH,
        "//div[@id='m4cd0065c-co_0_div']//*[@id='titlebar_hyperlink_8-co_0']//*[@id='titlebar_hyperlink_8-lbsignout']"))
)
logout = driver.find_element(
    By.XPATH,
    "//div[@id='m4cd0065c-co_0_div']//*[@id='titlebar_hyperlink_8-co_0']//*[@id='titlebar_hyperlink_8-lbsignout']")
logout.click()
time.sleep(2)
element_quit = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
    ec.visibility_of_element_located((By.XPATH, "//*[@id='returnFrm']//*[@id='submit']")))
return_login = driver.find_element(By.XPATH, "//*[@id='returnFrm']//*[@id='submit']")
return_login.click()
time.sleep(2)
driver.quit()

我做错什么了吗?我使用了一个"try-except"块,但还没能测试它,但如果"try-eexcept"是这样编码的,我希望得到反馈。我在手动工作时检查了DOM,除了创建新行或向工作订单添加内容时,DOM并没有真正改变。

这是"尝试除外"块:

for labor_row in range(0, len(pm_labor)):
            try:
                # Click on new labor for a new row to enter labor information
                element_new_labor = WebDriverWait(driver, 60, 5, ignore_exceptions).until(
                    ec.element_to_be_clickable((By.XPATH, "//*[@id='m4dfd8aef_bg_button_addrow-pb']")))
                new_labor = driver.find_element(By.XPATH, "//*[@id='m4dfd8aef_bg_button_addrow-pb']")
                new_labor.click()
                time.sleep(2)
                # Add labor ID from pm_labour list
                element_labor_id = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
                    ec.element_to_be_clickable((
                        By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:2]_txt-tb[R:" + str(labor_row) + "]']")))
                labor_id = driver.find_element(
                    By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:2]_txt-tb[R:" + str(labor_row) + "]']")
                labor_id.clear()
                slow_type(labor_id, pm_labor[labor_row][0].replace(" ", "", 1))
                time.sleep(2)
                # Add start date for PM from pm_labour list
                element_start_date = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
                    ec.element_to_be_clickable((
                        By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:6]_txt-tb[R:" + str(labor_row) + "]']")))
                start_date = driver.find_element(
                    By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:6]_txt-tb[R:" + str(labor_row) + "]']")
                start_date.clear()
                slow_type(start_date, pm_labor[labor_row][1].replace(" ", "", 1))
                time.sleep(2)
                # Add end date for PM from pm_labour list
                element_end_date = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
                    ec.element_to_be_clickable((
                        By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:7]_txt-tb[R:" + str(labor_row) + "]']")))
                end_date = driver.find_element(
                    By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:7]_txt-tb[R:" + str(labor_row) + "]']")
                end_date.clear()
                slow_type(end_date, pm_labor[labor_row][1].replace(" ", "", 1))
                time.sleep(2)
                # Add start time for PM from start_time list
                element_start_time = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
                    ec.element_to_be_clickable(
                        (By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:8]_txt-tb[R:" + str(labor_row) + "]']")))
                start_time_text = driver.find_element(
                    By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:8]_txt-tb[R:" + str(labor_row) + "]']")
                start_time_text.clear()
                slow_type(start_time_text, start_time[counter])
                time.sleep(2)
                # Add end time for PM from end_time list
                element_end_time = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
                    ec.element_to_be_clickable(
                        (By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:9]_txt-tb[R:" + str(labor_row) + "]']")))
                end_time_text = driver.find_element(
                    By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:9]_txt-tb[R:" + str(labor_row) + "]']")
                end_time_text.clear()
                slow_type(end_time_text, end_time[counter])
                time.sleep(3)
            except StaleElementReferenceException:
                # Delete row if exception is thrown and continue with loop
                element_delete_row = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
                    ec.element_to_be_clickable(
                        (By.XPATH,
                         "//*[@id='m900f2d81_tdrow_[C:9]_toggleimage-ti[R:" + str(labor_row) + "]']")))
                driver.find_element(
                    By.XPATH,
                    "//*[@id='m900f2d81_tdrow_[C:9]_toggleimage-ti[R:" + str(labor_row) + "]']").click()
                if labor_row == 0:
                    labor_row = 0
                    continue
                else:
                    labor_row += 0
                    continue

错误主要是:

StaleElementException: element is not attached to page'

发生错误的具体部分是:

(有时错误是在第一次迭代中抛出的,或者在前几次迭代中它会很好地工作,然后再次中断,这更令人沮丧!(

1.

pm_availability = []
for pm in range(0, len(pm_actuals[0])):
    time.sleep(1)
    ignore_exceptions = (NoSuchElementException, StaleElementReferenceException,)
    element_search_text_wo = WebDriverWait(driver, 120, 5, ignore_exceptions).until(
        ec.visibility_of_element_located((By.XPATH, "//input[@id='m6a7dfd2f_tfrow_[C:1]_txt-tb']")))
    search_text_wo = driver.find_element(By.XPATH, "//input[@id='m6a7dfd2f_tfrow_[C:1]_txt-tb']")
    search_text_wo.clear()
    slow_type(search_text_wo, pm_actuals[0][pm].replace(" ", "", 1))
    action.move_to_element(search_text_wo).send_keys(Keys.RETURN).release().perform()
    element_len_elements_list = WebDriverWait(driver, 120, 5, ignore_exceptions).until(
        ec.visibility_of_any_elements_located((By.XPATH, "//*[contains(@id, 'm6a7dfd2f_tbod_tdrow-tr[R:')]")))
    len_elements_list = driver.find_elements(By.XPATH, "//*[contains(@id, 'm6a7dfd2f_tbod_tdrow-tr[R:')]")
    if len(len_elements_list) != 0:
        # Check if PM status is WSCH
        if driver.find_element(
                By.XPATH,
                "/html/body/form/div/table[2]/tbody/tr/td/table/tbody/tr/td/table/tbody/tr/td/table/tbody/tr[2]/td/div/table/tbody/tr/td/div/table/tbody/tr/td/table/tbody/tr/td/div/table/tbody/tr/td/table/tbody/tr[2]/td/table/tbody/tr[2]/td/div/table/tbody/tr[3]/td/table/tbody/tr[3]/td/table/tbody/tr[4]/td[10]").text == "WSCH":
            pm_availability.append(pm_actuals[0][pm].replace(" ", "", 1))
            continue
        # If PM status is not WSCH, continue searching
        else:
            continue
    else:
        continue
        for labor_row in range(0, len(pm_labor)):
            try:
                # Click on new labor
                element_new_labor = WebDriverWait(driver, 60, 5, ignore_exceptions).until(
                    ec.element_to_be_clickable((By.XPATH, "//*[@id='m4dfd8aef_bg_button_addrow-pb']")))
                new_labor = driver.find_element(By.XPATH, "//*[@id='m4dfd8aef_bg_button_addrow-pb']")
                new_labor.click()
                time.sleep(2)
                # Add labor ID from pm_labour list
                element_labor_id = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
                    ec.element_to_be_clickable((
                        By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:2]_txt-tb[R:" + str(labor_row) + "]']")))
                labor_id = driver.find_element(
                    By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:2]_txt-tb[R:" + str(labor_row) + "]']")
                labor_id.clear()
                slow_type(labor_id, pm_labor[labor_row][0].replace(" ", "", 1))
                time.sleep(2)
                # Add start date for PM from pm_labour list
                element_start_date = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
                    ec.element_to_be_clickable((
                        By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:6]_txt-tb[R:" + str(labor_row) + "]']")))
                start_date = driver.find_element(
                    By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:6]_txt-tb[R:" + str(labor_row) + "]']")
                start_date.clear()
                slow_type(start_date, pm_labor[labor_row][1].replace(" ", "", 1))
                time.sleep(2)
                # Add end date for PM from pm_labour list
                element_end_date = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
                    ec.element_to_be_clickable((
                        By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:7]_txt-tb[R:" + str(labor_row) + "]']")))
                end_date = driver.find_element(
                    By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:7]_txt-tb[R:" + str(labor_row) + "]']")
                end_date.clear()
                slow_type(end_date, pm_labor[labor_row][1].replace(" ", "", 1))
                time.sleep(2)
                # Add start time for PM from start_time list
                element_start_time = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
                    ec.element_to_be_clickable(
                        (By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:8]_txt-tb[R:" + str(labor_row) + "]']")))
                start_time_text = driver.find_element(
                    By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:8]_txt-tb[R:" + str(labor_row) + "]']")
                start_time_text.clear()
                slow_type(start_time_text, start_time[counter])
                time.sleep(2)
                # Add end time for PM from end_time list
                element_end_time = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
                    ec.element_to_be_clickable(
                        (By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:9]_txt-tb[R:" + str(labor_row) + "]']")))
                end_time_text = driver.find_element(
                    By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:9]_txt-tb[R:" + str(labor_row) + "]']")
                end_time_text.clear()
                slow_type(end_time_text, end_time[counter])
                time.sleep(3)
            except StaleElementReferenceException:
                element_delete_row = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
                    ec.element_to_be_clickable(
                        (By.XPATH,
                         "//*[@id='m900f2d81_tdrow_[C:9]_toggleimage-ti[R:" + str(labor_row) + "]']")))
                driver.find_element(
                    By.XPATH,
                    "//*[@id='m900f2d81_tdrow_[C:9]_toggleimage-ti[R:" + str(labor_row) + "]']").click()
                if labor_row == 0:
                    labor_row = 0
                    continue
                else:
                    labor_row += 0
                    continue
        for rout in range(0, 3):
            if driver.find_element(By.XPATH, "//*[@id='md489b5d4-tb']").text != "COMP":
                # Click on the route button
                element_route = WebDriverWait(driver, 180, 20, ignore_exceptions).until(
                    ec.element_to_be_clickable((By.XPATH, "//*[@id='ROUTEWF_KAUWO_-tbb_anchor']")))
                route = driver.find_element(By.XPATH, "//*[@id='ROUTEWF_KAUWO_-tbb_anchor']")
                route.click()
                time.sleep(5)
                # Click on OK in the corresponding dialog box
                # element_click_ok = WebDriverWait(driver, 180, 20, ignore_exceptions).until(
                #     ec.element_to_be_clickable((By.XPATH, "//button[@type='button' and @id='md875c1f9-pb']")))
                #
                # click_ok = driver.find_element(By.XPATH, "//button[@type='button' and @id='md875c1f9-pb']")
                #
                # click_ok.click()
                driver.switch_to.alert.accept()
                time.sleep(5)
            else:
                pass
        element_list_view = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
            ec.visibility_of_element_located((By.XPATH,
                                              "//*[@id='m397b0593-tabs_backToList']/table/tbody/tr/td[1]")))
        list_view = driver.find_element(By.XPATH,
                                        "//*[@id='m397b0593-tabs_backToList']/table/tbody/tr/td[1]")
        time.sleep(2)
        list_view.click()
        time.sleep(2)
        pms_routed = [print(f"WO {pm_actuals[0][i]} is closed.")]
        counter += 1
        time.sleep(2)
        len(pm_availability) - 1
StaleElementException: element is not attached to page

意味着元素的先前引用现在已经过时,并且元素引用不再存在于页面的HTML DOM的当前状态中。

此异常背后的常见原因可能是以下任一原因:

  • 元素已经改变了它在HTML DOM中的位置
  • 元素不再附加到DOM树
  • 元素所在的网页已刷新
  • 元素的上一个实例已由JavaScript刷新

此用例

您的怀疑"when I start clicking on text fields on each new row that I get errors. It's as if adding a new row changes the whole DOM"是绝对正确的,因为"creates another table in the DOM"肯定会更改DOM树中先前标识的元素的位置,尽管其他元素保持不变。


参考文献

您可以在中找到一些相关的详细讨论

  • PageFactory中的StaleElementReference异常

相关内容

  • 没有找到相关文章

最新更新