Objective
Selenium locates a set of elements, and the batch operation loops when the click is error: Element not found in the Cache-perhaps the page has changed since it is looked up
Achieve the goal: Batch Click on the title, get the URL address of each page
The code is as follows:
```
# 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) # Prints the current page URL
Driver.back ()
```
Operation Result:
Http://www.cnblogs.com/yoyoketang/p/7259993.html
Traceback (most recent):
Selenium.common.exceptions.StaleElementReferenceException:Message:Element not found in the Cache-perhaps the page has Changed since it is looked up
A lot of people here will ask:
-"Why the first click can, the for loop second click on it?" ”
Since the first click, the page refreshed, we can manually click on the time, pay attention to the page, the page has a refresh action.
-"Why did you pinpoint the location and click on the error?" ”
The attributes of the element are unchanged after the page has been refreshed, but the element has changed, and all elements previously positioned have expired.
-"So how does it work?" ”
How to achieve this, this is the focus of this article.
First, analysis of the problem
1. When there is a click on the page, the page will be refreshed, in order to simulate the page refresh to see whether the element will change, we can refresh the page with refresh, and then see the changes in the elements before and after the 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) # before Refresh
Driver.refresh ()
All_new = Driver.find_elements_by_css_selector (". PostTitle2")
Print (all_new) # after Refresh
```
Operation Result:
[<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} ");
... The back is too long omitted]
2. It is obvious that the value inside the element has changed, so the first click is can point, after the point, the page refreshed, and then the elements on the page has changed, the second cycle or with the elements before the refresh to locate the click, Nature will error.
Second, the solution
1. For the page refresh, the previous element failure problem, in the For loop body can be repositioned once, overwriting the old before the line.
2. After the first acquisition of all elements, the total number is obtained through the Len function
3.for loop do not loop positioning elements of the list object, replaced by a range function to cycle
4. The reference code is as follows:
```
# 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 "Get Total number:%s"%s)
For I in range (s):
All[i].click ()
Time.sleep (2)
URL = Driver.current_url
Print (U "Get current page url:%s"%url)
Driver.back () # returns after the order is finished
# re-fetch element once
all = Driver.find_elements_by_css_selector (". PostTitle2")
```
Operation Result:
Selenium+python Automation 86-loop Click encounters the Pit