2017-02-25 14 views
0

我在Python 3中使用Selenium下面的代碼:明確等不硒一貫超時Python的

profile = webdriver.FirefoxProfile() 
profile.set_preference('webdriver.load.strategy', 'unstable') 
browser = webdriver.Firefox(profile) 
browser.set_page_load_timeout(10) 
url = 'my_url' 
while True: 
    try: 
     st = time.time() 
     browser.get(url) 
     print('Finished get!') 
     time.sleep(2) 
     wait = WebDriverWait(browser, 10) 
     element = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'div[my_attr="my_attr"]'))) 
     print('Success after {} seconds.'.format(round(time.time()-st))) 
     break 
    except: 
     print('Timed out after {} seconds.'.format(round(time.time()-st))) 
     print('Reloading') 
     continue 

從我的理解,用明確的等待在這裏(即使在不穩定的負載策略和頁面加載超時),應該發生的事情是頁面應該加載,它應該查找指定的元素,並且如果頁面在10秒內未加載或者在10秒內未找到該元素,則它應該超時並再次加載(由於while循環的try/except子句)。

但是,我發現它不會一直超時。例如,我有第一次10秒後加載超時的情況,但是一旦它重新加載,它不會超時,而是在140秒之後「成功」。或者有時它根本沒有時間,只是一直運轉直到成功。由於負載策略不穩定,我認爲頁面加載本身不會超時(更具體地說,「Finished get!」消息始終打印出來)。但我在這裏明確指出的等待似乎並不一致。我的代碼中是否有重寫超時的內容?我希望超時是一致的,如果頁面沒有加載或元素不在10秒內,我希望它超時並重新加載。即使成功,我也不希望它持續100多秒。

請注意,我在這裏使用不穩定的webdriver加載策略,因爲我要永久完成加載的頁面,所以我想直接瀏覽代碼,一旦找到需要的元素而不需要整個頁面完成加載。

+0

是否全部代碼?你沒有隱藏的等待埋在某處嗎?衆所周知,混合顯式和隱式等待會導致這樣的奇怪問題。我希望你的超時時間應該在10-22s之間。如果頁面加載超時時間爲10秒,如果未找到該元素,則爲22秒...對於顯式等待,頁面加載超時爲10秒+ .sleep()爲+ 10秒。 – JeffC

+0

您應該刪除'.sleep()'。使用它通常不是一個好習慣,反正這裏也不需要,因爲你之後有明確的等待權利。 '繼續'也可以安全地移除。 – JeffC

+0

我開始懷疑第二個'.get()'是不是中斷第一個,即使它仍然在運行,即使它會拋出一個錯誤。你能看到頁面在22秒後重新加載嗎?也許可以在'except'之後改變URL並且給它加上「cnn.com」或者一些東西,看它是否會在加載時重定向。即使這種方式有效,如果瀏覽器已經嘗試加載頁面,也不會再嘗試加載頁面。我不使用Python,所以我不能測試任何這些...對不起,我不能有更多的幫助,但這是一個有趣的問題。 – JeffC

回答

0

經過一些更多的測試後,我找到了問題的根源。這不是等待不起作用。問題是,定位器一直在佔用所有時間。我基本上通過編寫自己的等待函數並使用.find_element_by_css_selector()方法發現了這一點,這是所有運行時在100秒以上發生的地方。由於我的定位器的性質和頁面源的複雜性,當頁面幾乎完全加載時,定位器有時需要100多秒才能找到元素。定位時間並未計入等待時間。我認爲唯一的解決方案是寫一個更有效的定位器。