I solved an issue where I get a StaleElementReferenceException
on each of the dropdowns since I need to execute a click before the elements come into view. However, after catching the exception, I need the webdriver to go back to the previous line of code to click it into view again. Is there another argument I call, rather than the pass
argument, that could make that happen?
The pass
argument does not work, and since I am a little new to web scraping, am having a challenge seeing what else to do.
Here's my code:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import NoSuchElementException, ElementNotInteractableException, StaleElementReferenceException
from time import sleep
options1 = webdriver.ChromeOptions()
options1.add_experimental_option('excludeSwitches', ['enable-logging'])
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options1)
link = "https://www.compareandrecycle.co.uk/mobile-phones/apple-iphone-11"
driver.get(link)
sleep(5)
cookie_button = driver.find_element("xpath", "//span[@class='cookie_acceptButton__gs5MX']").click()
for x in wait.until(EC.visibility_of_all_elements_located((By.XPATH,"//div[@class='storage-selectors']/span"))):
size = x.text
print(size)
try:
variants = x.click()
except ElementNotInteractableException:
pass
network_options = driver.find_element("xpath", "//div[@class='network-options']//span[@class='selectboxit selectboxit-enabled selectboxit-btn']")
network_options.click()
sleep(3)
for elem in driver.find_elements("xpath", "//div[@class='network-options']//div[@class='selectboxit-options selectboxit-list']/li"):
try:
elem.click()
except StaleElementReferenceException:
pass
network = driver.find_element("xpath", "//div[@class='network-options']//span[@class='selectboxit selectboxit-enabled selectboxit-btn']/span[@class='selectboxit-text']").text
print(network)
sleep(3)
condition_options = driver.find_element("xpath","//div[@class='condition-options']//span[@class='selectboxit selectboxit-enabled selectboxit-btn']")
condition_options.click()
sleep(3)
for cons in driver.find_elements("xpath", "//div[@class='condition-options']//div[@class='selectboxit-options selectboxit-list']/li"):
try:
cons.click()
except StaleElementReferenceException:
pass
condition = driver.find_element("xpath", "//div[@class='condition-options']//span[@class='selectboxit selectboxit-enabled selectboxit-btn']/span[@class='selectboxit-text']").text
print(condition)
CodePudding user response:
driver.get('https://www.compareandrecycle.co.uk/mobile-phones/apple-iphone-11')
wait.until(EC.element_to_be_clickable((By.XPATH, "//span[contains(@class,'cookie_accept')]"))).click()
j=0
while True:
try:
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.network-options > div > div > span"))).click()
networks=wait.until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR,"div.selectboxit-options.selectboxit-list>li")))
networks[j].click()
i=0
while True:
try:
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.condition-options > div > div > span"))).click()
conditions=wait.until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR,"div.selectboxit-options.selectboxit-list>li")))
conditions[i].click()
i =1
except:
break
j =1
except:
break
You could either open it up and get the length and then loop or just loop until your erroring out and click on all the options.
Just add this to the top of the loop for all the sizes as well convert to Webdriver waits.
sizes = driver.find_elements(By.XPATH,"//span[contains(@class,'filter-box')]")
for i in range(len(sizes)):
driver.find_element(By.XPATH,f"(//span[contains(@class,'filter-box')] )[{i}]").click()