Issue with Radio Button using Selenium – Python

Question:

Selenium unable to locate element. Trying to navigate through a website that forces you to select certain elements as you go in order to define the final request. I am not sure, but from what I have found already on here the fact that the button is of Radio type may be important.

Here is the part of my code that works so far in order to launch driver, click past cookies, resize and scroll the page so that the element is visible. I do not believe that the resize and scroll is necessary from what I understand of finding elements by Xpath, but I did it anyway to eliminate possible causes for issue.

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Key
from webdriver_manager.chrome import ChromeDriverManager

url = "https://www.valencia.es/es/cas/atencion-ciudadana/comunicar-una-incidencia" 

driver = webdriver.Chrome(executable_path=r"/usr/local/bin/chromedriver")
time.sleep(1)

driver.get(url)
time.sleep(1)

Cookies = driver.find_element_by_xpath("/html/body/div[2]/div/div[2]/button[1]")
Cookies.click()

driver.maximize_window()
driver.execute_script("scroll(0, 1000)")

This is the element that I am trying to find:

<input type="radio" name="Grupo" value="GCOM-001" onclick="javascript: submit();">

And here is the code for my attempt to click with Xpath:

driver.find_element_by_xpath(".//input[@type='radio' and @value='GCOM-001']").click()

And my attempt using CSS_Selector:

driver.find_element_by_css_selector("input[type='radio'][value='GCOM-001']").click()

I am unable to find the element using either of these two methods (nor numerous other previous iterations). In both cases this is the returned error.

NoSuchElementException: Message: no such element: Unable to locate element:

Any help would be greatly appreciated.

Note: in case it matters, I am working on a Mac with OS13.1 and an M1 chip.

Asked By: NickBDA

||

Answers:

You can try like below by adding the explicitWait

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, 10)

element = wait.until(EC.element_to_be_clickable((By.XPATH, '//input[@type="radio" and @name="Grupo" and @value="GCOM-001"]')))

element.click()
Answered By: Akzy

The value i.e. GCOM-001 are dynamically generated and is bound to chage sooner/later. They may change next time you access the application afresh or even while next application startup. So can’t be used in locators.


As per the HTML

<input type="radio" name="Grupo" value="GCOM-001" onclick="javascript: submit();">

To click on the element you can use either of the following locator strategies:

  • Using css_selector:

    driver.find_element(By.CSS_SELECTOR, "input[name='Grupo'][onclick*='submit']").click()
    
  • Using xpath:

    driver.find_element(By.XPATH, "//input[@name='Grupo' and contains(@onclick, 'submit')]").click()
    

Ideally you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:

  • Using CSS_SELECTOR:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[name='Grupo'][onclick*='submit']"))).click()
    
  • Using XPATH:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@name='Grupo' and contains(@onclick, 'submit')]"))).click()
    
  • Note: You have to add the following imports :

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    
Answered By: undetected Selenium

You are not able to find the element simply because it is not present in the HTML of the page loaded by selenium. In fact if you run 'GCOM-001' in driver.page_source it prints False. This usually happens when there is an iframe in the page, hiding its content.

enter image description here

To access it we must first switch to it, using its id

driver.switch_to.frame('iframe_nsf')

Now 'GCOM-001' in driver.page_source prints True so we can finally click the button

driver.find_element(By.CSS_SELECTOR, 'input[value=GCOM-001]').click()

p.s. I suggest to use

WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.ID, "iframe_nsf")))

rather than driver.switch_to.frame('iframe_nsf'), because it waits (up to 20 seconds) to see if the iframe gets loaded in the page.

Answered By: sound wave