Voici ma tentative de solution complètement générique, en Python :
Tout d'abord, une fonction "wait" générique (utilisez un WebDriverWait si vous voulez, je les trouve moches) :
def wait_for(condition_function):
start_time = time.time()
while time.time() < start_time + 3:
if condition_function():
return True
else:
time.sleep(0.1)
raise Exception('Timeout waiting for {}'.format(condition_function.__name__))
Ensuite, la solution s'appuie sur le fait que Selenium enregistre un numéro d'identification (interne) pour tous les éléments d'une page, y compris l'élément de haut niveau. <html>
élément. Lorsqu'une page est rafraîchie ou chargée, elle reçoit un nouvel élément html avec un nouvel ID.
Ainsi, supposons que vous souhaitiez cliquer sur un lien dont le texte est "mon lien", par exemple :
old_page = browser.find_element_by_tag_name('html')
browser.find_element_by_link_text('my link').click()
def page_has_loaded():
new_page = browser.find_element_by_tag_name('html')
return new_page.id != old_page.id
wait_for(page_has_loaded)
Pour une aide plus pythique, réutilisable et générique, vous pouvez créer un gestionnaire de contexte :
from contextlib import contextmanager
@contextmanager
def wait_for_page_load(browser):
old_page = browser.find_element_by_tag_name('html')
yield
def page_has_loaded():
new_page = browser.find_element_by_tag_name('html')
return new_page.id != old_page.id
wait_for(page_has_loaded)
Et ensuite vous pouvez l'utiliser sur à peu près n'importe quelle interaction avec le sélénium :
with wait_for_page_load(browser):
browser.find_element_by_link_text('my link').click()
Je pense que c'est à l'épreuve des balles ! Et toi, qu'en penses-tu ?
Plus d'informations dans un article de blog à ce sujet ici .