2017-02-27 44 views
1

因此,我正在循環瀏覽一堆網頁。目前,網頁的結構都與後退按鈕和前進按鈕(//span/a)[2]相同。出於某種原因,我可以循環瀏覽第一頁(有時是第二頁)。但是我繼續獲得StaleElementReferenceException遍歷頁面並在Python中獲取StaleElementReferenceException Selenium

下面是相關的代碼:

for x in range(0,5): 
    print 'page %d' %(x) 
    WebDriverWait(driver, 10).until(
     EC.presence_of_element_located((By.XPATH, "(//span/a)[2]")) 
    ) 
    listItems = driver.find_elements_by_xpath("//td[@class='CourseCode']/a") 
    for element in listItems: 
     elementText = element.text 
     print(elementText) 
     writeFile.write(element.text + '\n') 
    driver.find_element_by_xpath("(//span/a)[2]").click() 

尤其這裏是堆棧跟蹤:

Traceback (most recent call last): 
File "getList.py", line 21, in lookup 
addListItems(driver, courseCodeFile) 
File "getList.py", line 44, in addListItems 
elementText = element.text 
File "/home/francisco/.local/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py", line 73, in text 
return self._execute(Command.GET_ELEMENT_TEXT)['value'] 
File "/home/francisco/.local/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py", line 494, in _execute 
return self._parent.execute(command, params) 
File "/home/francisco/.local/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 236, in execute 
self.error_handler.check_response(response) 
File "/home/francisco/.local/lib/python2.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 192, in check_response 
raise exception_class(message, screen, stacktrace) 
StaleElementReferenceException: Message: The element reference is stale. Either the element is no longer attached to the DOM or the page has been refreshed. 

我已經嘗試了一堆沒有用。奇怪的是,如果沒有循環,我能夠讓這個函數正常工作兩頁。

在RTE之前的注意事項中,它將打印前一頁中獲得的前兩個元素listItems的文本。

回答

1

您可以通過在WebDriverWait中使用stalenessOfExpected Condition來避免StaleElementReferenceExpection


StaleElementReferenceExpection發生在兩種情況爲例:

  1. 的元件已被完全刪除。
  2. 該元素不再附加到DOM。

當您使用共同定位器在所有的網頁,一旦你點擊一個元素,硒仍引用到上一個頁面中的定位器(DOM is NOT yet updated, still referencing to the old web page)

一個簡單的解決方案是增加time.sleep在代碼的結束,使DOM將得到更新,定位器將在DOM應用新的網頁。

for x in range(0,5): 
    print 'page %d' %(x) 
    WebDriverWait(driver, 10).until(
     EC.presence_of_element_located((By.XPATH, "(//span/a)[2]")) 
    ) 
    listItems = driver.find_elements_by_xpath("//td[@class='CourseCode']/a") 
    for element in listItems: 
     elementText = element.text 
     print(elementText) 
     writeFile.write(element.text + '\n') 
    driver.find_element_by_xpath("(//span/a)[2]").click() 
    import time 
    time.sleep(0.5) //0.5 seconds 

另一種解決方案是檢查在每個網頁的獨特元素,(如果你使用if-else & indexing等可能的)

+0

只是一些小的澄清,這可能無法在for loop。那麼WebDriverWait的重點是什麼?據我所知,這是等到該元素被加載。但是在這種情況下,它是否仍然引用舊的DOM? – Francisco

+1

是的,WebDriverWait將等待一些條件滿足,比如Presence_Of_Element,Visibiliti_Of_Element等等。在您的情況下,因爲定位符是相同的,它們都出現在當前頁面和前一頁面的DOM中,並給出異常。在這裏尋找更多細節http://stackoverflow.com/questions/16166261/selenium-webdriver-how-to-resolve-stale-element-reference-exception&https://seleniumhq.github.io/selenium/docs/api /java/org/openqa/selenium/support/ui/ExpectedConditions.html#stalenessOf-org.openqa.selenium.WebElement-。試着用'stalenessOf'的條件代替睡眠。 –

+0

使用'staleness_of',它完美運行。如果你想更新你的答案,在'click()'之後的'(// span/a)[2]''上使用'staleness_of'。我很樂意選擇這個解決方案。 – Francisco