Aqui está minha tentativa de uma solução completamente genérica, em Python:
Primeiro, uma função genérica de "espera" (use um WebDriverWait, se quiser, acho-os feios):
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__))
Em seguida, a solução conta com o fato de que o selênio registra um número de identificação (interno) para todos os elementos em uma página, incluindo o <html>
elemento de nível superior . Quando uma página é atualizada ou carregada, ela obtém um novo elemento html com um novo ID.
Então, supondo que você queira clicar em um link com o texto "meu link", por exemplo:
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)
Para um auxiliar genérico Python, reutilizável e reutilizável, você pode criar um gerenciador de contexto:
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)
E então você pode usá-lo em praticamente qualquer interação de selênio:
with wait_for_page_load(browser):
browser.find_element_by_link_text('my link').click()
Eu acho que é à prova de balas! O que você acha?
Mais informações em um post do blog aqui