selenium+python自動化88-批量操作循環點擊報錯:Element not found in the cache - perhaps the page has changed since it was looked up


前言

selenium定位一組元素,批量操作循環點擊的時候會報錯:Element not found in the cache - perhaps the page has changed since it was looked up

實現目標:批量點擊標題,獲取每個頁面的url地址

代碼如下:

# coding:utf-8

from selenium import webdriver

driver = webdriver.Firefox()
driver.get("https://www.cnblogs.com/yoyoketang/")

all = driver.find_elements_by_css_selector(".postTitle2")

for i in all:
    i.click()
    print(driver.current_url)   # 打印當前頁url
    driver.back()

運行結果:
http://www.cnblogs.com/yoyoketang/p/7259993.html
Traceback (most recent call last):

selenium.common.exceptions.StaleElementReferenceException: Message: Element not found in the cache - perhaps the page has changed since it was looked up

這里不少人就會問了:

  • “為什么第一次點擊可以,for循環第二次點擊就不行了呢?”

由於第一次點擊后,頁面刷新了,我們可以手工點擊的時候,注意觀察頁面,頁面是有刷新動作的。

  • “為什么明明定位到了,點擊會報錯呢?”

頁面刷新后元素的屬性是沒變,但是element卻變了,所有之前定位的元素element都過期了。

  • “那么如何實現呢?”

如何實現,這個才是本篇重點要講的。

分析問題

1.當頁面上有點擊行為的時候,頁面是會刷新的,為了模擬頁面刷新后查看元素是不是會變,我們可以用refresh刷新頁面,然后查看刷新前后元素的變化。

# coding:utf-8

from selenium import webdriver
import time
driver = webdriver.Firefox()
driver.get("https://www.cnblogs.com/yoyoketang/")

all = driver.find_elements_by_css_selector(".postTitle2")
print(all)  # 刷新前

driver.refresh()
all_new = driver.find_elements_by_css_selector(".postTitle2")
print(all_new)  # 刷新后

運行結果:
[<selenium.webdriver.remote.webelement.WebElement (session="36801e98-3a57-41b1-a58e-021fe925fd57", element="{88a2f797-3833-4ea4-a734-72c5c59800ff}")>, <selenium.webdriver.remote.webelement.WebElement (session="36801e98-3a57-41b1-a58e-021fe925fd57", element="{529248de-6ca0-43d9-8747-34d7dad28c6c}")>,
...后面太長省略了]

2.很明顯element里面的值發生了變化,所以第一次點擊是可以點的,點完之后,頁面刷新了,然后頁面上的元素已經發生變化了,第二次循環的時候還是用刷新前的元素去定位點擊的,自然就會報錯了。

解決方案

1.針對頁面刷新后,之前的元素失效問題,在for循環體里面可以重新定位一次,覆蓋掉之前舊的就行了。

2.第一次獲取全部元素后,通過len函數獲取總個數

3.for循環的時候不要循環定位元素的list對象,換成range函數去循環

4.參考代碼如下:

# coding:utf-8

from selenium import webdriver
import time
driver = webdriver.Firefox()
driver.get("https://www.cnblogs.com/yoyoketang/")

all = driver.find_elements_by_css_selector(".postTitle2")
s = len(all)
print(u"獲取總個數:%s"%s)

for i in range(s):
    all[i].click()
    time.sleep(2)
    url = driver.current_url
    print(u"獲取當前頁面url:%s"%url)
    driver.back()  # 點完之后返回
    # 重新獲取一次元素
    all = driver.find_elements_by_css_selector(".postTitle2")

運行結果:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM