Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

selenium.common.exceptions.TimeoutException while clicking on a button using expected_conditions presence_of_element_located in Selenium Python

Ask Question

I want to create an automatic creation for Nike accounts. For that I need to add a phone number. I am coding with Python 3, Selenium and the Chrome Webdriver. This is my current code:

    driver.get('https://www.nike.com/de/member/settings')
    element2 = WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, "/html/body/div[3]/div/div[6]/div[2]/div[2]/div/form/div[2]/div[5]/div/div/div/div[2]/button")))
    driver.execute_script("arguments[0].click();", element2)
    time.sleep(1)

This codes only works sometimes, I am often getting this error message:

      Traceback (most recent call last):
      File "C:/Users/Marten/PycharmProjects/NikeSNKRS/main.py", line 239, in <module>
        element2 = WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, "/html/body/div[3]/div/div[6]/div[2]/div[2]/div/form/div[2]/div[5]/div/div/div/div[2]/button")))
      File "C:\Users\Marten\PycharmProjects\NikeSNKRS\venv\lib\site-packages\selenium\webdriver\support\wait.py", line 80, in until
        raise TimeoutException(message, screen, stacktrace)
    selenium.common.exceptions.TimeoutException: Message: 

Do you maybe know a way to fix this? If you want to inspect the page, I created an account for you with which you can go onto the site and inspect the site. Click to go to Site

Account credentials:

Mail: eXrWi9TfA5XSfNcu4uv2q1@peter.de
Password: 5By3oq1Bw

I want to click this button:

I wish I could tell you that this works 100% of the time (it doesn't) but perhaps it will get you a bit closer. I think one of the problems is that when you login the settings for Account are not open and visible (at least that is always the case for me) and you have to first click on the Account selection at the left to reveal the Mobil settings. Unfortunately, even that does not work 100% of the time, at least not with the following code (I am using basic element click calls). But I offer this up for what it's worth:

from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_experimental_option('excludeSwitches', ['enable-logging'])
driver = webdriver.Chrome(options=options)
    driver.implicitly_wait(10) # wait up to 10 seconds before calls to find elements time out
    driver.get('https://www.nike.com/member/settings')
    input('pausing for login ...') # to allow manual login
    driver.get('https://www.nike.com/member/settings')
    elem = driver.find_element_by_xpath('/html/body/div[3]/div/div[6]/div[1]/div[1]/div') # Account settings
    elem.click()
    elem = driver.find_element_by_xpath('/html/body/div[3]/div/div[6]/div[2]/div[2]/div/form/div[2]/div[5]/div/div/div/div[2]/button')
    elem.click()
finally:
    input('pausing for inspection') # to allow inspection
    driver.quit()

To click on the element with text as Hinzufügen instead of presence_of_element_located() 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, "button[aria-label='Mobilnummer hinzufügen']"))).click()
    
  • Using XPATH and aria-label attribute:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[@aria-label='Mobilnummer hinzufügen']"))).click()
    
  • Using XPATH and innerText attribute:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[contains(., 'Hinzufügen')]"))).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
                    Thanks, but i am using proxys from different countries. And I think your solution would only work with german proxys, or when the language is set to german.
    – Marten
                    Sep 8, 2020 at 12:42
                    @MatrixSpielt I didn't consider the case of language locale. But the text you were speaking about i.e. Hinzufügen should be located by the locator strategies without any failure.
    – undetected Selenium
                    Sep 8, 2020 at 12:45
                    Okay, ive tried your method, but I constantly get this error code now: Traceback (most recent call last):   File "C:/Users/Marten/PycharmProjects/NikeSNKRS/testdelete.py", line 221, in <module>     WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[aria-label='Mobilnummer hinzufügen']"))).click()   File "C:\Users\Marten\PycharmProjects\NikeSNKRS\venv\lib\site-packages\selenium\webdriver\support\wait.py", line 80, in until     raise TimeoutException(message, screen, stacktrace) selenium.common.exceptions.TimeoutException: Message:
    – Marten
                    Sep 9, 2020 at 13:23
    

    I was quite new to coding, I still am, and I just wanted to create a little script for myself. Also I was quite unexperienced with XPaths. I recommend everybody who stumbles upon this issue, to read through this article.

    I used this XPath, instead: //div[@class="mex-mobile-input"]/div/div/div[2]/button

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.

  •