Wait until loader disappears python selenium
Asked Answered
L

4

25
<div id="loader-mid" style="position: absolute; top: 118.5px; left: 554px; display: none;">
    <div class="a">Loading</div>
    <div class="b">please wait...</div>
</div>

And want to wait until it disappears. I have following code but it wait sometimes too long and at some point of code it suddenly freeze all process and I don't know why.

from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait

self.wait = WebDriverWait(driver, 10)

self.wait.until(EC.invisibility_of_element_located((By.XPATH, "//*[@id='loader_mid'][contains(@style, 'display: block')]")))

and also I tried this one:

self.wait.until_not(EC.presence_of_element_located((By.XPATH, "//*[@id='loader_mid'][contains(@style, 'display: block')]")))

I don't know exactly how to check but maybe my element is always present on the page and selenium thought that it is there, the only thing that changes is parameter display changes from none to block. I think I can get attribute like string and check if there is word "block" but it is so wrong I thing... Help me please.

Laundromat answered 28/9, 2014 at 16:21 Comment(3)
Have you tried checking for the visibility of an element that is hidden behind the loader?Easel
Yes and it didn't help me. But somehow now second variant works. strange.Laundromat
Yea that is pretty weird.Easel
H
42

Reiterated your answer (with some error handling) to make it easier for people to find the solution :)

Importing required classes:

from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.common.exceptions import TimeoutException

Configuration variables:

SHORT_TIMEOUT  = 5   # give enough time for the loading element to appear
LONG_TIMEOUT = 30  # give enough time for loading to finish
LOADING_ELEMENT_XPATH = '//*[@id="xPath"]/xPath/To/The/Loading/Element'

Code solution:

try:
    # wait for loading element to appear
    # - required to prevent prematurely checking if element
    #   has disappeared, before it has had a chance to appear
    WebDriverWait(driver, SHORT_TIMEOUT
        ).until(EC.presence_of_element_located((By.XPATH, LOADING_ELEMENT_XPATH)))

    # then wait for the element to disappear
    WebDriverWait(driver, LONG_TIMEOUT
        ).until_not(EC.presence_of_element_located((By.XPATH, LOADING_ELEMENT_XPATH)))

except TimeoutException:
    # if timeout exception was raised - it may be safe to 
    # assume loading has finished, however this may not 
    # always be the case, use with caution, otherwise handle
    # appropriately.
    pass 
Haerr answered 1/12, 2016 at 5:25 Comment(2)
This is such a genius answer. I was struggling with this exact idea for ages and this is the perfect solution. Thank youProceleusmatic
I used it for waiting a modal dialog to appear and then dissapear.. work perfect! ThanksTriatomic
F
11

Use expected condition : invisibility_of_element_located

This works fine for me.

from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait


WebDriverWait(driver, timeout).until(EC.invisibility_of_element_located((By.ID, "loader-mid")))
Folder answered 25/7, 2019 at 6:18 Comment(0)
L
1

The following code creates an infinite loop until the element disappears:

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException

while True:
        try:
            WebDriverWait(driver, 1).until(EC.presence_of_element_located((By.XPATH, 'your_xpath')))
        except TimeoutException:
            break
Liscomb answered 25/5, 2018 at 3:21 Comment(1)
The issue with this, is the element may not have had time to load first, so it will instantly break out of the loop and continue. Also infinite loops are rarely a good thing, unless there is a way to cancel them and they should usually have some kind of sleep within the loop to prevent overuse of resources (cpu).Haerr
H
0

Ok, here is how i solved this issue for my project, imports

from selenium.common.exceptions import TimeoutException
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait as wait

Now the code part

browser = webdriver.Chrome(service=Service("./chromedriver.exe"))
browser.get("https://dashboard.hcaptcha.com/signup?type=accessibility")
try:
    d = wait(browser, 10).until(EC.invisibility_of_element_located((By.ID, 'loader-mid')))
    if d: # just a check you can ignore it.
      print("yes")
      sleep(3)
    else:
      print("F")
except TimeoutException:
  print("timeout error occurred.")
  pass
browser.quit()

Or you can use Implicit wait

driver.implicitly_wait(10) # seconds
# do something after...
Holdback answered 23/10, 2022 at 21:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.