2015-09-20 45 views
2

我正在使用Selenium Webdriver與Python。我有一些循環遍歷HTML表格的代碼。它在列中查找值。 我越來越元素不再有效。 這是一個競爭條件,因爲如果所有行都在網頁上加載,它有時會起作用。Webdriver等待顯示StaleElementReferenceException消息元素不再有效當我通過表循環循環

StaleElementReferenceException: Message: Element is no longer valid 

我正在使用Webdriver等待。也許我的語法不正確。這是我的代碼片段。 如果有人能夠在這裏給予幫助,解決這個問題不再有效的問題將會很有幫助。

from selenium.webdriver.support import expected_conditions as EC 
from selenium.webdriver.common.by import By 
from selenium.webdriver.support.ui import WebDriverWait 
from selenium.common.exceptions import NoSuchElementException 
from Locators.locators import MainPageLocators 

def is_mappings_details_saved(self, name, dataset, feed, variable): 
    try: 
     WebDriverWait(self.driver, 20).until(EC.presence_of_all_elements_located((By.TAG_NAME, 'td'))) 
     table_id = self.get_element(*MainPageLocators.mappings_details_savedpage_table) 
     #rows = table_id.find_elements(By.TAG_NAME, "tr") 
     rows = WebDriverWait(self.driver, 20).until(EC.presence_of_all_elements_located(table_id.find_elements(By.TAG_NAME, "tr"))) 
     for row in rows: 
      time.sleep(1) 
      # Get the columns 
      col_name = row.find_elements(By.TAG_NAME, "td")[1] # This is the Name column 
      col_variable = row.find_elements(By.TAG_NAME, "td")[2] # This is the Variable column 
      col_feed = row.find_elements(By.TAG_NAME, "td")[3] # This is the Feed column 
      col_data_category = row.find_elements(By.TAG_NAME, "td")[4] # This is the Data Category column 
      col_dataset = row.find_elements(By.TAG_NAME, "td")[6] # This is the Dataset column 
      col_datamap = row.find_elements(By.TAG_NAME, "td")[7] # This is the Datamap column 
      if (col_name.text == name) and (col_variable.text == variable) and (col_feed.text == feed) and (col_data_category.text == "Main") and (col_dataset.text == dataset) and (col_datamap.text == self.datamap_name): 
       return True 
     return False 
    except NoSuchElementException, e: 
     return False 

下面的行是問題所在

rows = WebDriverWait(self.driver, 20).until(EC.presence_of_all_elements_located(table_id.find_elements(By.TAG_NAME, "tr"))) 

該網頁顯示的列(名,變量訂閱等)的表。 每一行都有每列的數據。例如。露西,姓名,數據源。 我正在if語句的每一行檢查數據是否正確。 我需要等待加載表中的所有行以避免陳舊的元素異常。 等待整個表加載的最佳方式是什麼?


這裏是工作的解決方案:

JeffC建議等待只表集裝箱裝載。無需等待列和行。我現在已經開始工作了。我也把self.driver.implicitly_wait(20)放在基類中。 這裏是工作的解決方案:

class BasePage(object): 

def __init__(self, driver): 
    self.driver = driver 
    self.driver.implicitly_wait(20) 

class MappingsPage(BasePage): 
    def is_mappings_details_saved(self, name, dataset, feed, variable):  
     table_id = WebDriverWait(self.driver, 20).until(EC.presence_of_element_located((*MainPageLocators.mappings_details_savedpage_table))) 
     rows = table_id.find_elements(By.TAG_NAME, "tr") 
     for row in rows: 
      # Get the columns 
      col_name = row.find_elements(By.TAG_NAME, "td")[1] 
      col_variable = row.find_elements(By.TAG_NAME, "td")[2] 
     etc... 

感謝, 里亞茲

回答

1

我很困惑什麼你正在嘗試做的。您等待所有TD s在第一行的頁面(這似乎很奇怪)...爲什麼你然後等待所有的TR s在一些TABLE下3行?我的猜測是table_id陳舊,因爲您在*MainPageLocators中使用了錯誤的引用。除非動態加載表,否則應該只能等待頁面上的單個元素加載。一旦完成,整個DOM應該被加載。您可以等待容器TABLE,如果它有一個ID等沒有更多的代碼或相關的HTML,我不知道我可以幫你進一步。

+0

我等着要加載的所有列,然後加載所有行的計數器。然後我可以從每列和每行中獲取值。這是做錯的方法。我會嘗試等待表格被加載。該表具有ID。謝謝你的支持。 –

+0

我試過等待表加載。我收到錯誤Element不再有效。我的代碼如下:table_id = wait.until(EC.presence_of_element_located((By.ID,'data_configuration_mappings_ct_fields_body'))),下一行是:rows = table_id.find_elements(By.TAG_NAME,「tr」) –

+0

什麼是請等待表加載的語法? –

0

JeffC建議等待表格容器加載。無需等待列和行。我現在已經開始工作了。我也把self.driver.implicitly_wait(20)在基類 - 在這裏是解決方案:

class BasePage(object): 

def __init__(self, driver): 
    self.driver = driver 
    self.driver.implicitly_wait(20) 

class MappingsPage(BasePage): 
table_id = WebDriverWait(self.driver, 20).until(EC.presence_of_element_located((*MainPageLocators.mappings_details_savedpage_table))) 
rows = table_id.find_elements(By.TAG_NAME, "tr") 
for row in rows: 
    # Get the columns 
    col_name = row.find_elements(By.TAG_NAME, "td")[1] 
    col_variable = row.find_elements(By.TAG_NAME, "td")[2] 
etc... 
+0

採取別人給你的答案,把它當作自己的答案,然後給自己信用,這通常是不好的形式。如果你想發佈最終代碼,你可以編輯你的問題,放一個分隔線,然後解釋這裏的工作解決方案。 – JeffC

+0

我在我的問題中添加了分隔線,並將工作解決方案放在那裏。謝謝。 –

0

我有一個類似的問題與長期循環的WebdriverWait和弄僵就可以了。我解決的方法是在循環外創建一個實用函數。 在循環中調用該函數並將參數傳遞給它。

def try_path(driver,foo): 
# this is an utility to circumvent the stale error 
try: 
    foo = WebDriverWait(driver).until(EC.presence_of_element_located((By.TAG_NAME, "#yourtablehere"))) 
    return foo 

except WebDriverException as e: 
    return try_path(foo) 

您可能要實現以防萬一