Trying to locate an element in a webpage but getting NoSuchElementException

Question:

I am trying to get the webdriver to click a button on the site random.org The button is a generator that generates a random integer between 1 and 100. It looks like this:

The generator button

After inspecting the webpage, I found the corresponding element on the webpage looks something like this:

The HTML skeleton

It is inside an iframe and someone suggested that I should first switch over to that iframe to locate the element, so I incorporated that in my code but I am constantly getting NoSuchElementException error. I have attached my code and the error measage below for your reference. I can’t understand why it cannot locate the button element despite referencing the ID, which is supposed to unique in the entire document.

The code:

from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Edge()

driver.get("https://www.random.org/")

driver.implicitly_wait(15)

driver.switch_to.frame(driver.find_element(By.TAG_NAME, "iframe"))

button = driver.find_element(By.CSS_SELECTOR, "input[id='hnbzsqjufzxezy-button']")

button.click()

The error message:

The error message

Asked By: Siddharth Das

||

Answers:

Make sure that there are no more Iframes on the page. If there are a few an not only one do this:

iframes = driver.find_elements(By.CSS, 'iframe')
// try switching to each iframe:
driver.switch_to.frame(iframes[0])
driver.switch_to.frame(iframes[1])

You can’t find the button because its name contain random letters. Every time you will refresh the page you can see that the name value will change. So, do this:

button = driver.findElement(By.CSS, 'input[type="button"][value="Generate"]')
button.click()
Answered By: Tal Angel

There are several issues with your code:

  1. First you need to close the cookies banner
  2. The locator of the button is wrong. It’s id is dynamic.
  3. You need to use WebDriverWait to wait for elements clickability.
    The following code works:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
options = Options()
options.add_argument("start-maximized")

webdriver_service = Service('C:webdriverschromedriver.exe')
driver = webdriver.Chrome(service=webdriver_service, options=options)
url = 'https://www.random.org/'
driver.get(url)
wait = WebDriverWait(driver, 10)

wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[onclick*='all']"))).click()
wait.until(EC.frame_to_be_available_and_switch_to_it((By.TAG_NAME, "iframe")))
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[id*='button']"))).click()
Answered By: Prophet