Search code examples
pythonhtmlseleniumwebdriverwait

No such element error when trying to get attribute of button tags


I am trying to get the attribute of some button tags.

driver.get('https://migroskurumsal.com/magazalarimiz/')

try:
    select = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.ID, 'stores'))
    )
    print('Dropdown is ready!')
except TimeoutException:
    print('Took too much time!')

select = Select(driver.find_element(By.ID, 'stores'))

select.select_by_value('2')
shopList = driver.find_element(By.ID, "shopList")
try:
    WebDriverWait(driver, 10).until(
        EC.visibility_of_all_elements_located((By.XPATH, "//ul[@id='shopList']/li/div/button"))
    )
    print('Shoplist is ready!')
except TimeoutException:
    print('Took too much time!')
    driver.quit()

print(shopList.get_attribute("class"))

li_items = shopList.find_elements(By.TAG_NAME, 'li')

for item in li_items:
    
    first = item.find_element(By.TAG_NAME, 'div')
    second = first.find_element(By.TAG_NAME, 'button')
    coord = second.get_attribute("onclick")
    print(coord)

I am waiting for all of the button elements to load. However when I try to print the onclick attribute of all button tags it only prints the first two, then throws a "NoSuchElementException: Message: no such element: Unable to locate element". But I could not figure out why. You can look at the html by going to "https://migroskurumsal.com/magazalarimiz/" and choosing "Migros" from the rightmost dropdown. I kindly request your help. Thank you.


Solution

  • visibility_of_all_elements_located will not really wait for All the elements matching the passed locator to become visible.
    Actually, this method is similar to visibility_of_element_located method with only one difference: visibility_of_element_located returns a single web element while visibility_of_all_elements_located returns a list of web elements.
    To achieve what you are looking for here, you can add a short delay of 1 second after applying the visibility_of_all_elements_located method to let all the web elements to be loaded.
    Try this please:

    driver.get('https://migroskurumsal.com/magazalarimiz/')
    
    try:
        select = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, 'stores')))
        print('Dropdown is ready!')
    except TimeoutException:
        print('Took too much time!')
    
    select = Select(driver.find_element(By.ID, 'stores'))
    
    select.select_by_value('2')
    shopList = driver.find_element(By.ID, "shopList")
    try:
        WebDriverWait(driver, 10).until(EC.visibility_of_all_elements_located((By.XPATH, "//ul[@id='shopList']/li/div/button")))
        time.sleep(1)
    
        print('Shoplist is ready!')
    except TimeoutException:
        print('Took too much time!')
        driver.quit()
    
    print(shopList.get_attribute("class"))
    
    li_items = shopList.find_elements(By.TAG_NAME, 'li')
    
    for item in li_items:
        
        first = item.find_element(By.TAG_NAME, 'div')
        second = first.find_element(By.TAG_NAME, 'button')
        coord = second.get_attribute("onclick")
        print(coord)