標籤:返回 for迴圈 自動 css_ mes mos cee 查看 重點
前言
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")
```
運行結果:
selenium+python自動化86-迴圈點擊遇到的坑