İşte Python'da tamamen genel bir çözüme yönelik girişimim:
İlk olarak, genel bir "bekle" işlevi (isterseniz bir WebDriverWait kullanın, onları çirkin buluyorum):
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__))
Daha sonra çözüm, selenyumun üst düzey <html>
öğe de dahil olmak üzere bir sayfadaki tüm öğeler için bir (dahili) kimlik numarası kaydetmesine dayanır . Bir sayfa yenilendiğinde veya yüklendiğinde, yeni bir kimliğe sahip yeni bir html öğesi alır.
Dolayısıyla, "bağlantım" metni içeren bir bağlantıya tıklamak istediğinizi varsayarsak, örneğin:
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)
Daha fazla Pythonic, yeniden kullanılabilir, genel bir yardımcı için bir bağlam yöneticisi yapabilirsiniz:
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)
Ve sonra hemen hemen her selenyum etkileşiminde kullanabilirsiniz:
with wait_for_page_load(browser):
browser.find_element_by_link_text('my link').click()
Sanırım bu kurşun geçirmez! Ne düşünüyorsun?
Bununla ilgili bir blog gönderisinde daha fazla bilgi burada