यहाँ पायथन में एक पूरी तरह से सामान्य समाधान पर मेरा प्रयास है:
सबसे पहले, एक सामान्य "प्रतीक्षा" फ़ंक्शन (यदि आप चाहें तो 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()
मुझे लगता है कि बुलेटप्रूफ है! तुम क्या सोचते हो?
इसके बारे में एक ब्लॉग पोस्ट में अधिक जानकारी यहाँ