Home > front end >  How to identify the object with in the HTML using Selenium and Python
How to identify the object with in the HTML using Selenium and Python

Time:03-29

Might be a bit of an edge use case, but I need to identify and then click on an object on a login page. The page itself is dynamically generated and all of the (4) buttons are labeled as such:

button  tabindex="0" type="button">

With the full breakdown of the button I'm trying to click being:

<button  tabindex="0" type="button"><span ><div  params="[object Object]"><div ><svg  focusable="false" viewBox="0 0 24 24" aria-hidden="true"><path d="M21 6h-2v9H6v2c0 .55.45 1 1 1h11l4 4V7c0-.55-.45-1-1-1zm-4 6V3c0-.55-.45-1-1-1H3c-.55 0-1 .45-1 1v14l4-4h10c.55 0 1-.45 1-1z"></path></svg></div><div >Q&A</div></div><div >Security Questions</div></span><span ></span></button>

I've tried mapping the XPATH, using CSS Selectors, trying to find the strings of text embedded in in the button, and even trying to find the SVG by using the following:

driver.find_element(by=By.XPATH , value = '//path[@d="

Any ideas how I can get Selenium to identify this object without any static identifiers?

Here's everything I've got so far:

#I know most of these are extraneous references :/
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support.expected_conditions import presence_of_element_located
from selenium.webdriver.support import expected_conditions as EC
import time
import sys

url = 'https://***.com'
chrome_driver_path = '/Users/***/chromedriver'

chrome_options = Options()
chrome_options.add_argument('--headless')

webdriver = webdriver.Chrome(
  executable_path=chrome_driver_path, options=chrome_options
)

with webdriver as driver:
    wait = WebDriverWait(driver, 10)
    driver.get(url)
    wait.until(presence_of_element_located((By.ID, "password")))

    inputUsername = driver.find_element_by_id("loginID")
    inputPassword = driver.find_element_by_id("password")
    findLoginButton = driver.find_element_by_id("submit-button")

    inputUsername.send_keys('[username]')
    inputPassword.send_keys('[password]')
    findLoginButton.click()
    
    # element1 = driver.find_element_by_css_selector("div.MuiBox-root.jss135.jss107.jss134")
    # wait.until(presence_of_element_located(element1))
    # element1.click()

    driver.find_element(by=By.XPATH , value = '//path[@d="M21 6h-2v9H6v2c0 .55.45 1 1 1h11l4 4V7c0-.55-.45-1-1-1zm-4 6V3c0-.55-.45-1-1-1H3c-.55 0-1 .45-1 1v14l4-4h10c.55 0 1-.45 1-1z"]')
    #CSS_SELECTOR,value="#root > div > div > ^MuiBox-root^ > ^MuiBox-root^ > form > div > div.MuiCollapse-container.MuiCollapse-entered > div > div > div > button:nth-child(5)]")
    #find_element_by_xpath("/html/body/div/div/div/div[2]/div[2]/form/div/div[1]/div/div/div/button[4]").click()

    driver.close()

CodePudding user response:

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

  • Using XPATH and the innerText Security Questions:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[contains(@class, 'MuiButtonBase-root')]/span[@class='MuiButton-label']//div[text()='Security Questions']"))).click()
    
  • Using XPATH and the innerText Q&A:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[contains(@class, 'MuiButtonBase-root')]/span[@class='MuiButton-label']//div[text()='Q&A']"))).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
    

CodePudding user response:

I think your problem is that your locator is wrong, which is why your element isn't being found.

Try this:

driver.find_element(by=By.XPATH, "//button[contains(.//div, 'Security Questions')]")

This Xpath will return a button element that contains a div with the text "Security Questions."

  • Related