Home > database >  How to find the find the div element using Selenium and Python
How to find the find the div element using Selenium and Python

Time:07-28

Selenium is unable to find an element on a webpage, here is the python code

element = driver.find_element(By.CLASS_NAME, "_13NKt copyable-text selectable-text")

Here is an image of the element it is supposed to find, class highlighted

html code

And here is the important line of the error message:

selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"._13NKt copyable-text selectable-text"}
  (Session info: chrome=103.0.5060.134)

CodePudding user response:

The By-strategy By.CLASS_NAME internally uses By.CSS_SELECTOR and simply prefixes the locator with . - which is also visible in your error message

{"method":"css selector","selector":"._13NKt copyable-text selectable-text"}

But that's not a valid CSS selector for an element that includes all those classes, instead you have to "concatenate" them with . (simply replace the spaces between the classes with ".")

So either:

driver.find_element(By.CLASS_NAME, "_13NKt.copyable-text.selectable-text")

or use By.CSS_SELECTOR directly:

driver.find_element(By.CSS_SELECTOR, "._13NKt.copyable-text.selectable-text")

the only difference being the leading .

CodePudding user response:

You have to take care of a couple of things here:

  • By.CLASS_NAME accepts only one argument. So you won't be able to pass multiple classes.
  • The classnames e.g. _13NKt 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.
  • The <div> is having the attribute contenteditable="true".

Solution

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

  • Using CSS_SELECTOR:

    element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div[data-testid='pluggable-input-body'][role='textbox']")))
    
  • Using XPATH:

    element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[@data-testid='pluggable-input-body' and @role='textbox']")))
    
  • 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:

Selenium can't identify multiple class name of an element using CLASS_NAME, instead use CSS_SELECTOR.

element = driver.find_element(By.CSS_SELECTOR, "._13NKt.copyable-text.selectable-text")

The class name can be dynamic,I would suggest use data-testid property.

element = driver.find_element(By.CSS_SELECTOR, "[data-testid='pluggable-input-body']")

CodePudding user response:

When using By.CLASS_NAME the given string is matched against each class name of you element. Your element has three different classes:

  1. _13NKt
  2. copyable-text
  3. selectable-text

So the string "_13NKt copyable-text selectable-text" does not match any one of them.

If you really need to find the element that has all of these classes, you can use driver.find_element(By.CSS_SELECTOR, "._13NKt.copyable-text.selectable-text") instead (see docs). You may also be able to use XPath or something else, if that is more up your alley.

CodePudding user response:

Try:

element = WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.CSS_SELECTOR, '._13NKt.copyable-text.selectable-text')))

You will also need to import:

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

If it doesn't work, post your url.

  • Related