Ось моя спроба цілком загального рішення в Python:
По-перше, загальна функція "зачекати" (використовуйте WebDriverWait, якщо вам подобається, я вважаю їх некрасивими):
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__))
Далі, рішення покладається на те, що селен записує (внутрішній) ідентифікаційний номер для всіх елементів сторінки, включаючи <html>
елемент верхнього рівня . Коли сторінка оновлюється або завантажується, вона отримує новий html-елемент з новим ідентифікатором.
Отже, якщо припустити, що ви хочете натиснути на посилання з текстом "моє посилання", наприклад:
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)
Для отримання більш пітонічного, багаторазового використання, загального помічника, ви можете створити контекстний менеджер:
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)
І тоді ви можете використовувати його майже на будь-якій взаємодії з селеном:
with wait_for_page_load(browser):
browser.find_element_by_link_text('my link').click()
Я вважаю, що це куленепробивна! Що ти думаєш?
Більше інформації в публікації блогу тут