Python Selenium wait for several elements to load

First and foremost the elements are AJAX elements.

Now, as per the requirement to locate all the desired elements and create a list, the simplest approach would be to induce WebDriverWait for the visibility_of_all_elements_located() and you can use either of the following Locator Strategies:

  • Using CSS_SELECTOR:

    elements = WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, "ul.ltr li[id^='t_b_'] > a[id^='t_a_'][href]")))
    
  • Using XPATH:

    elements = WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.XPATH, "//ul[@class="ltr"]//li[starts-with(@id, 't_b_')]/a[starts-with(@id, 't_a_') and starts-with(., 'Category')]")))
    
  • 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
    

Incase your usecase is to wait for certain number of elements to be loaded e.g. 10 elements, you can use you can use the lambda function as follows:

  • Using >:

    myLength = 9
    WebDriverWait(driver, 20).until(lambda driver: len(driver.find_elements_by_xpath("//ul[@class="ltr"]//li[starts-with(@id, 't_b_')]/a[starts-with(@id, 't_a_') and starts-with(., 'Category')]")) > int(myLength))
    
  • Using ==:

    myLength = 10
    WebDriverWait(driver, 20).until(lambda driver: len(driver.find_elements_by_xpath("//ul[@class="ltr"]//li[starts-with(@id, 't_b_')]/a[starts-with(@id, 't_a_') and starts-with(., 'Category')]")) == int(myLength))
    

You can find a relevant discussion in How to wait for number of elements to be loaded using Selenium and Python


References

You can find a couple of relevant detailed discussions in:

Leave a Comment