Home > database >  Selenium Python not finding element in first try, its finds in second try
Selenium Python not finding element in first try, its finds in second try

Time:10-13

I have below Selenium Python code to find the element in the aspx web page in dialog box.

for loop runs twice, during the first run its not finding the radio button. during second iteration its finds the radio button. In the loop I am just switching to frame 0.

I like to understand, why it’s not finding the element in first try? how it was able to find the element in second run?

**Sample code with drive option **

web_url = config['ARCHER_URL']
options = Options()

options.page_load_strategy = 'normal'
s = Service(web_driver)
driver = webdriver.Chrome(service=s, options=options)
driver.get(web_url)
logger.info(f"Loading the site {web_url}")
driver.implicitly_wait(10)
time.sleep(5)
driver.switch_to.frame(0)


frames = [0, 1]
for frame in frames:
    logger.info(f"Switching to frame {frame}")
    driver.switch_to.frame(0)
    try:
        element = driver.find_element(By.ID, "ExcludeButton")
        if element:
            logger.success("Found Radio button")
            element.click()
            break
    except NoSuchElementException as e:
        logger.warning("element not in this frame: "   repr(e))

log message during the run

 - Switching to frame 0
 - element not in this frame: NoSuchElementException('no such element: Unable to locate el
 - Switching to frame 1
 - Found Radio button
            

CodePudding user response:

A probably better way would be using Waits:

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
...
wait = WebDriverWait(driver, 20)
...
wait.until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, '//iframe[@name="great_iframe_name"]')))

wait.until(EC.element_to_be_clickable((By.ID, 'ExcludeButton'))).click()

Relevant documentation for Waits: https://www.selenium.dev/documentation/webdriver/waits/#explicit-wait

CodePudding user response:

Looks like the page is loading or changing after some action when you trying to find that element while you did not define driver.implicitly_wait so it is set to it default value of 0 that means if driver.find_element doesn't find the element instantly it throws exception.
To avoid such situations the best practice is to use WebDriverWait expected_conditions explicit waits. With them you can use for element presence, visibility, clickability and more.
So, your code can be improved as following:

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

wait = WebDriverWait(driver, 20)
try:
    logger.info(f"Switching to frame {frame}")
    driver.switch_to.frame(0)
    wait.until(EC.element_to_be_clickable((By.ID, 'ExcludeButton'))).click()
    logger.success("Found Radio button")
    break
except NoSuchElementException as e:
    logger.warning("element not in this frame: "   repr(e))

The code above should work for the first attempt and not go to except block ever.

  • Related