nonamethoughtof
nonamethoughtof

Reputation: 11

Python Selenium can't find element, clicking first button loads the second button

I am trying to use Selenium to download a file by clicking a "Query" button and then a "Download" button. The "Download" button is not available until the "Query" button is clicked. I am able to locate and click the "Query" button but I get an error no matter what find_element method I use when trying to find the "Download" button. Also, the id of the "Download" button is dynamic, so it cannot be identified by ID.

Query Button:

<button type="submit" class="btn mt-5 btn-primary btn-md">Query</button>

Download Button:

<div data-v-38979de7="" id="export_1659030977844" class="btn btn-info"> Download </div>
driver.implicitly_wait(3)
driver.find_element("xpath", './/button[@class="btn mt-5 btn-primary btn-md"]').click
driver.implicitly_wait(3)
driver.find_element("xpath", './/div[@class="btn btn-info"]')
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":".//div[@class="btn btn-info"]"} 

Upvotes: 1

Views: 415

Answers (2)

undetected Selenium
undetected Selenium

Reputation: 193088

To click on the element with text as Download you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:

  • Using XPATH and normalize-space():

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[@class='btn btn-info' and normalize-space()='Download']"))).click()
    
  • Using XPATH and contains():

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[@class='btn btn-info' and contains(., 'Download')]"))).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
    

Upvotes: 1

Barry the Platipus
Barry the Platipus

Reputation: 10460

Normally you would select that button by ID, however, in this case, it seems that ID is being generated automatically, on the fly, based on file id. You can try clicking that second button with:

WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[text()=' Download ']"))).click()

You also need to import:

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

Upvotes: 1

Related Questions