發現太多人不會用等待了,部落客今天實在是忍不住要跟大家講講等待的必要性。
很多人在群組裡問,這個下拉框定位不到、那個彈出框定位不到…各種定位不到,其實大多數情況下就是兩種問題:1 有frame, 2 沒有加等待。殊不知,你的程式碼運行速度是什麼量級的,而瀏覽器加載渲染速度又是什麼量級的,就好比閃電俠和凹凸曼約好去打怪獸,然後閃電俠打完回來之後問凹凸曼你為啥還在穿鞋沒出門?凹凸曼分分中內心一萬隻羊駝飛過,欺負哥速度慢,哥不跟你玩了,拋個異常撂挑子了。
那麼怎麼能照顧到凹凸曼緩慢的載入速度呢?只有一個辦法,那就是等嘍。說到等,又有三種等法,且聽博主一一道來:
1. 強制等待
第一種也是最簡單粗暴的一種辦法就是強制等待sleep(xx),強制讓閃電俠等xx時間,不管凹凸曼能不能跟上速度,還是已經提前到了,都必須等xx時間。
看程式碼:
# -*- coding: utf-8 -*- from selenium import webdriver from time import sleep driver = webdriver.Firefox() driver.get('https://huilansame.github.io') sleep(3) # 强制等待3秒再执行下一步 print driver.current_url driver.quit()
這種叫強制等待,不管你瀏覽器是否載入完了,程式都得等待3秒,3秒一到,繼續執行下面的程式碼,作為調試很有用,有時也可以在程式碼裡這樣等待,不過不建議總用這種等待方式,太死板,嚴重影響程式執行速度。
2. 隱性等待
第二種辦法叫隱性等待,implicitly_wait(xx),隱性等待的意義是:閃電俠和凹凸曼約定好,不論閃電俠去哪兒,都要等凹凸曼xx秒,如果凹凸曼在這段時間內來了,則倆人立即出發去打怪獸,如果凹凸曼在規定時間內沒到,則閃電俠自己去,那自然就等著凹凸曼給你拋異常吧。
看程式碼:
# -*- coding: utf-8 -*- from selenium import webdriver driver = webdriver.Firefox() driver.implicitly_wait(30) # 隐性等待,最长等30秒 driver.get('https://huilansame.github.io') print driver.current_url driver.quit()
隱形等待是設定了一個最長等待時間,如果在規定時間內網頁載入完成,則執行下一步,否則一直等到時間截止,然後再執行下一步。注意這裡有一個弊端,那就是程式會一直等待整個頁面載入完成,也就是一般情況下你看到瀏覽器標籤欄那個小圈不再轉,才會執行下一步,但有時候頁面想要的元素早就在載入完成了,但是因為個別js之類的東西特別慢,我仍得等到頁面全部完成才能執行下一步,我想等我要的元素出來之後就下一步怎麼辦?有辦法,這就要看selenium提供的另一種等待方式──顯性等待wait了。
需要特別說明的是:隱性等待對整個driver的周期都起作用,所以只要設定一次即可,我曾看到有人把隱性等待當成了sleep在用,走哪兒都來一下…
3. 顯性等待
第三種辦法就是顯性等待,WebDriverWait,配合該類別的until()和until_not()方法,就能夠根據判斷條件而進行靈活地等待了。它主要的意思就是:程式每隔xx秒看一眼,如果條件成立了,則執行下一步,否則繼續等待,直到超過設定的最長時間,然後拋出TimeoutException。
先看個程式碼範例:
# -*- coding: utf-8 -*- from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By driver = webdriver.Firefox() driver.implicitly_wait(10) # 隐性等待和显性等待可以同时用,但要注意:等待的最长时间取两者之中的大者 driver.get('https://huilansame.github.io') locator = (By.LINK_TEXT, 'CSDN') try: WebDriverWait(driver, 20, 0.5).until(EC.presence_of_element_located(locator)) print driver.find_element_by_link_text('CSDN').get_attribute('href') finally: driver.close()
上例中,我們設定了隱性等待和顯性等待,在其他運算中,隱性等待起決定性作用,在WebDriverWait..中顯性等待起主要作用,但要注意的是:最長的等待時間取決於兩者之間的大者,此例中為20,如果隱性等待時間> 顯性等待時間,則該句代碼的最長等待時間等於隱性等待時間。
我們主要用到了WebDriverWait類別與expected_conditions模組,下面部落客帶大家細看這兩個模組:
WebDriverWait
wait模組的WebDriverWait類別是顯性等待類,先看下它有哪些參數與方法:
#selenium.webdriver.support.wait.WebDriverWait(类) __init__ driver: 传入WebDriver实例,即我们上例中的driver timeout: 超时时间,等待的最长时间(同时要考虑隐性等待时间) poll_frequency: 调用until或until_not中的方法的间隔时间,默认是0.5秒 ignored_exceptions: 忽略的异常,如果在调用until或until_not的过程中抛出这个元组中的异常, 则不中断代码,继续等待,如果抛出的是这个元组外的异常,则中断代码,抛出异常。默认只有NoSuchElementException。 until method: 在等待期间,每隔一段时间调用这个传入的方法,直到返回值不是False message: 如果超时,抛出TimeoutException,将message传入异常 until_not 与until相反,until是当某元素出现或什么条件成立则继续执行, until_not是当某元素消失或什么条件不成立则继续执行,参数也相同,不再赘述。 method message
看了以上內容基本上很清楚了,呼叫方法如下:
WebDriverWait(driver, 逾時時長, 呼叫頻率, 忽略異常).until(可執行方法, 逾時時傳回的資訊)
expected_conditions
expected_conditions是selenium的一个模块,其中包含一系列可用于判断的条件: selenium.webdriver.support.expected_conditions(模块) 这两个条件类验证title,验证传入的参数title是否等于或包含于driver.title title_is title_contains 这两个人条件验证元素是否出现,传入的参数都是元组类型的locator,如(By.ID, 'kw') 顾名思义,一个只要一个符合条件的元素加载出来就通过;另一个必须所有符合条件的元素都加载出来才行 presence_of_element_located presence_of_all_elements_located 这三个条件验证元素是否可见,前两个传入参数是元组类型的locator,第三个传入WebElement 第一个和第三个其实质是一样的 visibility_of_element_located invisibility_of_element_located visibility_of 这两个人条件判断某段文本是否出现在某元素中,一个判断元素的text,一个判断元素的value text_to_be_present_in_element text_to_be_present_in_element_value 这个条件判断frame是否可切入,可传入locator元组或者直接传入定位方式:id、name、index或WebElement frame_to_be_available_and_switch_to_it 这个条件判断是否有alert出现 alert_is_present 这个条件判断元素是否可点击,传入locator element_to_be_clickable 这四个条件判断元素是否被选中,第一个条件传入WebElement对象,第二个传入locator元组 第三个传入WebElement对象以及状态,相等返回True,否则返回False 第四个传入locator以及状态,相等返回True,否则返回False element_to_be_selected element_located_to_be_selected element_selection_state_to_be element_located_selection_state_to_be 最后一个条件判断一个元素是否仍在DOM中,传入WebElement对象,可以判断页面是否刷新了 staleness_of
#
上面是所有17個condition,與until、until_not組合能夠實現很多判斷,如果能自己靈活封裝,將會大大提高腳本的穩定性。
今天就分享這些內容,有什麼問題可以留言給我交流,希望能幫助到有需要的同學。謝謝大家對本站的支持!
更多Python selenium 三種等待方式解讀相關文章請關注PHP中文網!