0

I want to click this element called "Select File", it is a button but i am unable to click it using selenium command. The the element I am about to click is as follows:

<label for="file" class="pb default" style="display: inline-block;margin: 5px 10px;">Select File</label>

the script I am using to click for that element is:

_test_=browser.find_elements_by_class_name("pb default")
_test_.click()

It gives an exception like this:

Traceback (most recent call last):
  File "z:\test_selenium_impossible_click.py", line 58, in
<module>
    _test_.click()
AttributeError: 'list' object has no attribute 'click'

I am using latest firefox version with latest webdriver for firefox

UPDATE : i have edited the code to become like this :

_test_=browser.find_element_by_class_name("pb default")
_test_.click()

but now it gives output like this :

  Traceback (most recent call last):
  File "z:\automator-python\test_selenium_impossible_click.py", line 57, in <module>
    _test_=browser.find_element_by_class_name("pb default")
  File "C:\Python\Python38-32\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 564, in find_element_by_class_name
    return self.find_element(by=By.CLASS_NAME, value=name)
  File "C:\Python\Python38-32\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 976, in find_element
    return self.execute(Command.FIND_ELEMENT, {
  File "C:\Python\Python38-32\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "C:\Python\Python38-32\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: .pb default

i have tried the other ways like what has been suggested to me but it still gives output like what i mentioned above...do you know how to solve this??

2 Answers2

0

The problem is not missing attributes, it in the element locating.

find_elements_* return a list, not a single element, so you can't click it.

by_class_name recive a single class as parameter, you sent two.

To locate the element by multiple classes use css_selector

find_element_by_css_selector('.pb.default')
Guy
  • 46,488
  • 10
  • 44
  • 88
  • hello, i have changed that according to your suggestion, but now the output for the code is like this : selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: .pb default do you know the solution for that? thx – DeadlyKitten999 Feb 20 '20 at 13:46
0

This error message...

AttributeError: 'list' object has no attribute 'click'

...implies that AttributeError was raised when you tried to invoke click() on a List element.


click() method can be invoked only on a WebElement but not on a List.

In your code trials you have used find_elements_by_class_name() (note the s in elements) which returns a List. So when you try to invoke click() on the List, AttributeError is raised. So first of all you need to replace find_elements_by_class_name() with find_element_by_class_name().

Additionally, you can't pass multiple classes as arguments to find_element_by_class_name() which will result in invalid selector: Compound class names not permitted error. To pass multiple classes you have to use either or as a Locator Strategy and you can use either of the following solutions:

  • Using css_selector:

    _test_ = browser.find_elements_by_css_selector(".pb.default")
    _test_.click()
    
  • Using xpath:

    _test_ = browser.find_element_by_xpath("//*[@class='pb default']")
    _test_.click()
    

However, as per best practices, I would suggest to use a granular locator adding the tag_name as follows:

  • Using css_selector:

    _test_ = browser.find_elements_by_css_selector("label.pb.default[for='file']")
    _test_.click()
    
  • Using xpath:

    _test_ = browser.find_element_by_xpath("//label[@class='pb default' and @for='file']")
    _test_.click()
    

Update

Ideally, while invoking click() 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, "label.pb.default[for='file']"))).click()
    
  • Using xpath:

    WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//label[@class='pb default' and @for='file']"))).click()
    

Reference

You can find a relevant detailed discussion in:

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • hello, i have changed that according to your suggestion, but now the output for the code is like this : selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: .pb default do you know the solution for that? thx – DeadlyKitten999 Feb 20 '20 at 13:45
  • @CybersAndroidz Checkout the updated answer and let me know the status. – undetected Selenium Feb 20 '20 at 13:54