python中的selenium入門(mén)超詳細(xì)教程
selenium,一個(gè)第三方庫(kù),可以通過(guò)給driver發(fā)送命令來(lái)操作瀏覽器,以達(dá)到模擬人操作瀏覽器,實(shí)現(xiàn)網(wǎng)頁(yè)自動(dòng)化、測(cè)試等,減少了重復(fù)性工作。
selenium的工作的基本架構(gòu)如下:
安裝
本文是在python環(huán)境下使用selenium,使用瀏覽器是Chrome,系統(tǒng)是win10系統(tǒng)。
python環(huán)境的配置這里就不多說(shuō)了
selenium安裝:pip install selenium
Driver安裝:
- chromedriver下載:
- 國(guó)內(nèi)鏡像下載地址:https://registry.npmmirror.com/binary.html?path=chromedriver
- 打開(kāi)chrome瀏覽器,打開(kāi)chrome://settings/help頁(yè)面,即可查看chrome版本號(hào)
- 根據(jù)Chrome的版本號(hào)下載對(duì)應(yīng)版本或稍微高于該版本的chromedirver,然后解壓
- 環(huán)境變量配置:
- 配置系統(tǒng)環(huán)境變量path,將chromedirver的解壓包所在目錄添加進(jìn)去,然后點(diǎn)擊確定進(jìn)行保存
查看是否配置成功
使用
selenium的使用基本思路如下:
- 步驟1:打開(kāi)瀏覽器
- 步驟2:操作瀏覽器或驗(yàn)證頁(yè)面數(shù)據(jù)等
- 步驟3:關(guān)閉瀏覽器進(jìn)程
示例:
from selenium import webdriver if __name__ == "__main__": # 由于selenium是通過(guò)driver去操作瀏覽器的,所以我們需要對(duì)應(yīng)瀏覽器的driver對(duì)象 driver = webdriver.Chrome() # 打開(kāi)百度首頁(yè) driver.get("https://www.baidu.com") # 操作瀏覽器或驗(yàn)證頁(yè)面數(shù)據(jù)等 print("xxx") # 關(guān)閉瀏覽器進(jìn)程 driver.quit()
瀏覽器驅(qū)動(dòng)
從前面的selenium工作原理我們可以了解到,我們的代碼并不是直接去操作瀏覽器的,而是通過(guò)給瀏覽器驅(qū)動(dòng)driver發(fā)送命令,driver去操作瀏覽器的,簡(jiǎn)單點(diǎn)理解就是跟selenium對(duì)接的是driver,所以我們都是先創(chuàng)建一個(gè)driver去進(jìn)行后面的操作。
驅(qū)動(dòng)對(duì)象WebDriver
selenium支持的瀏覽器驅(qū)動(dòng)有:Firefox、Chrome、Ie、Edge、Safari等瀏覽器的驅(qū)動(dòng)(需要自己手動(dòng)安裝對(duì)應(yīng)的瀏覽器驅(qū)動(dòng))
selenium創(chuàng)建瀏覽器驅(qū)動(dòng)對(duì)象的語(yǔ)法如下:
import time from selenium import webdriver # 創(chuàng)建 Firefox 瀏覽器驅(qū)動(dòng)對(duì)象 driver = webdriver.Firefox() # 創(chuàng)建 Chrome 瀏覽器驅(qū)動(dòng)對(duì)象 driver = webdriver.Chrome() # 創(chuàng)建 IE 瀏覽器驅(qū)動(dòng)對(duì)象 driver = webdriver.Ie() # 創(chuàng)建 Edge 瀏覽器驅(qū)動(dòng)對(duì)象 driver = webdriver.Edge() # 創(chuàng)建 Safari 瀏覽器驅(qū)動(dòng)對(duì)象 driver = webdriver.Safari()
打開(kāi)網(wǎng)頁(yè)
驅(qū)動(dòng)對(duì)象WebDriver的創(chuàng)建相當(dāng)于打開(kāi)了瀏覽器,我們打開(kāi)瀏覽器肯定是想訪問(wèn)某個(gè)網(wǎng)頁(yè)的,所以接下來(lái)就是打開(kāi)網(wǎng)頁(yè),對(duì)應(yīng)的方法是:get(url)
get(url)
是WebDriver對(duì)象的方法,所以需要先創(chuàng)建WebDriver對(duì)象。
關(guān)閉瀏覽器
相關(guān)操作執(zhí)行完成后,最后肯定是要關(guān)閉瀏覽器的,不然打開(kāi)太多瀏覽器,會(huì)占用資源。關(guān)閉瀏覽器有2種方式:close()
和quit()
方法 | 描述 |
---|---|
close() | 關(guān)閉當(dāng)前標(biāo)簽頁(yè)面 |
quit() | 關(guān)閉瀏覽器 |
注:如果當(dāng)前瀏覽器只有一個(gè)標(biāo)簽頁(yè),close()有時(shí)能達(dá)到quit()的效果,因?yàn)橛行g覽器判斷沒(méi)有標(biāo)簽頁(yè)的時(shí)候會(huì)默認(rèn)為關(guān)閉瀏覽器,比如Chrome。
示例:
import time from selenium import webdriver from selenium.webdriver.common.by import By if __name__ == "__main__": driver = webdriver.Chrome() driver.implicitly_wait(10) # 打開(kāi)百度首頁(yè) driver.get("https://www.baidu.com") # 點(diǎn)擊 新聞 ,新標(biāo)簽頁(yè)打開(kāi)百度新聞 driver.find_element(By.LINK_TEXT, "新聞").click() # 在百度首頁(yè)點(diǎn)擊 視頻,打開(kāi)百度視頻 driver.find_element(By.LINK_TEXT, "視頻").click() time.sleep(2) # 關(guān)閉百度首頁(yè)這個(gè)標(biāo)簽頁(yè) driver.close() time.sleep(2) # 關(guān)閉瀏覽器 driver.quit()
執(zhí)行結(jié)果如下:
從關(guān)閉瀏覽器這里可以看出來(lái),WebDriver對(duì)象的當(dāng)前頁(yè)面并不是我們看到的新標(biāo)簽頁(yè),如果想切換到其他頁(yè)面,就需要用到switch_to()方法,這個(gè)后面系列再具體介紹。
定位元素
瀏覽器頁(yè)面除了給我們展示數(shù)據(jù)外,還需要我們?nèi)ゲ僮黜?yè)面,比如點(diǎn)擊、長(zhǎng)按、拖拽、雙擊指定元素等,在操作元素時(shí),我們得讓driver知道要操作的元素,即selenium需要給到元素的定位。
find_element()
早期的selenium提供了針對(duì)id、name、xpath等多種方式的具體方法來(lái)定位到具體的元素,比如find_element_by_id()、find_element_by_name()等,在后續(xù)的升級(jí)中,這些方法被棄用了,現(xiàn)在統(tǒng)一使用find_element(by=By.ID, value=None)
方法,該方法包含了id、name、xpath等定位方式
find_element(by=By.ID, value=None)是WebDriver對(duì)象用于定位元素的方法,返回對(duì)應(yīng)元素對(duì)象(WebElement),我們的點(diǎn)擊、拖拽等操作都是在元素對(duì)象的基礎(chǔ)上進(jìn)行的
參數(shù)說(shuō)明by:指定按照對(duì)應(yīng)的方式來(lái)定位元素
- By.ID,根據(jù)查找標(biāo)簽中的id屬性來(lái)定位元素
- By.NAME,根據(jù)查找標(biāo)簽中的name屬性來(lái)定位元素
- By.CLASS_NAME,根據(jù)class屬性指定的值來(lái)查找元素
- By.CSS_SELECTOR,根據(jù)css選擇器的方式來(lái)查找元素
- By.XPATH,根據(jù)XPath語(yǔ)法來(lái)查找元素
- By.LINK_TEXT,查找文本精確匹配的a標(biāo)簽元素
- By.PARTIAL_LINK_TEXT,查找文本模糊匹配的a標(biāo)簽元素
- By.TAG_NAME,根據(jù)標(biāo)簽名稱(chēng)來(lái)查找元素,不太好用,不常用
value:元素位置,字符串類(lèi)型
注意:XPath使用范圍比較廣,但是查找速度比較慢,id、name、class其實(shí)是根據(jù)css_selector來(lái)實(shí)現(xiàn)的,css_selector查找元素比較快;一個(gè)頁(yè)面中,id和name一般是唯一的(人為的約定俗成,非強(qiáng)制),具體使用哪種方式,要依據(jù)頁(yè)面的改動(dòng)程度、前端頁(yè)面的層級(jí)等確定。
XPath語(yǔ)法參考:XPath入門(mén)
Python2 Selenium元素定位的實(shí)現(xiàn)(8種)
示例:
如下示例是打開(kāi)百度首頁(yè),搜索”春節(jié)“,然后點(diǎn)擊”百度首頁(yè)“返回百度首頁(yè),在首頁(yè)中點(diǎn)擊”幫助中心“進(jìn)入幫助中心頁(yè)面
import time from selenium import webdriver from selenium.webdriver.common.by import By if __name__ == "__main__": # 定義一個(gè)WebDriver對(duì)象 driver = webdriver.Chrome() # 打開(kāi)百度首頁(yè) driver.get("https://www.baidu.com/") # 常用的屬性定位方式來(lái)定位搜索框 # we = driver.find_element(By.ID, "kw") # 根據(jù)ID屬性定位搜索框 # we = driver.find_element(By.NAME, "wd") # 根據(jù)NAME屬性定位搜索框 # we = driver.find_element(By.CLASS_NAME, "s_ipt") # 根據(jù)CLASS_NAME屬性定位搜索框 # 通過(guò)CSS選擇器定位搜索框 # we = driver.find_element(By.CSS_SELECTOR, "#kw") # '#'符號(hào)表示id,#kw表示id="kw" # we = driver.find_element(By.CSS_SELECTOR, ".s_ipt") # '.'符號(hào)表示class,.s_ipt表示class="s_ipt" # we = driver.find_element(By.CSS_SELECTOR, '[autocomplete="off"]') # []內(nèi)指定屬性及其值,表示根據(jù)屬性來(lái)定位元素 # 通過(guò)xpath定位搜索框 we = driver.find_element(By.XPATH, "http://input[@id='kw']") # 往搜索框里輸入”春節(jié)“的搜索內(nèi)容 we.send_keys("春節(jié)") time.sleep(3) # 精準(zhǔn)匹配a標(biāo)簽的文本內(nèi)容”百度首頁(yè)“,然后點(diǎn)擊,進(jìn)入百度首頁(yè) we1 = driver.find_element(By.LINK_TEXT, "百度首頁(yè)") we1.click() time.sleep(2) # 模糊匹配a標(biāo)簽的文本內(nèi)容包含”幫助“,點(diǎn)擊,進(jìn)入 幫助中心 頁(yè)面 we2 = driver.find_element(By.PARTIAL_LINK_TEXT, "幫助") we2.click() time.sleep(2) # 終止相關(guān)進(jìn)程 driver.quit()
find_elements()
find_element(by=By.ID, value=None)
是返回單個(gè)的WebElement對(duì)象,find_elements(by=By.ID, value=None)
是返回一個(gè)列表(List)對(duì)象,列表中都是WebElement對(duì)象。
如圖,想獲取百度首頁(yè)的百度熱搜下詞條內(nèi)容,當(dāng)前頁(yè)面一共有6條,find_element()肯定不符合預(yù)期,find_elements()滿(mǎn)足要求。
import time from selenium import webdriver from selenium.webdriver.common.by import By if __name__ == "__main__": # 定義一個(gè)WebDriver對(duì)象 driver = webdriver.Chrome() # 打開(kāi)百度首頁(yè) driver.get("https://www.baidu.com/") # 通過(guò)class屬性定位元素 wes = driver.find_elements(By.CLASS_NAME, "title-content-title") print(f"find_elements()返回的數(shù)據(jù)類(lèi)型是:{type(wes)}") for we in wes: print("----------------------------") print(we) print(we.text) time.sleep(3) # 終止相關(guān)進(jìn)程 driver.quit()
執(zhí)行結(jié)果如下:
find_elements()返回的數(shù)據(jù)類(lèi)型是:<class 'list'>
----------------------------
<selenium.webdriver.remote.webelement.WebElement (session="daf7a5e628209860b164358803cd4801", element="02a46e1c-eeed-446d-b78f-2fd261c5d189")>
紅紅火火舞新春
----------------------------
<selenium.webdriver.remote.webelement.WebElement (session="daf7a5e628209860b164358803cd4801", element="c7fe0312-9739-4256-ae6b-6be8a4d5f610")>
春耕備耕忙
----------------------------
<selenium.webdriver.remote.webelement.WebElement (session="daf7a5e628209860b164358803cd4801", element="b2effc84-5b55-4cfc-814c-3d8509f30647")>
知情人:仍在搜尋胡鑫宇飯卡
----------------------------
<selenium.webdriver.remote.webelement.WebElement (session="daf7a5e628209860b164358803cd4801", element="bb8af466-32ad-45c4-b9e2-e2eb1af0bb6f")>
官方人士:錄音筆在深圳恢復(fù)數(shù)據(jù)
----------------------------
<selenium.webdriver.remote.webelement.WebElement (session="daf7a5e628209860b164358803cd4801", element="fdfeb919-1070-4c04-9e71-e6c17975efcd")>
保時(shí)捷官網(wǎng)12.4萬(wàn)元帕納梅拉遭搶購(gòu)
----------------------------
<selenium.webdriver.remote.webelement.WebElement (session="daf7a5e628209860b164358803cd4801", element="4ea5b289-73a5-4cf2-8782-06d8ad08e1f3")>
5萬(wàn)年一遇綠色彗星逼近地球
元素操作
我們獲取到元素之后,需要對(duì)元素進(jìn)行操作,比如在輸入框中輸入內(nèi)容,點(diǎn)擊按鈕等操作。
WebElement對(duì)象有多個(gè)屬性和方法,但常用的就幾個(gè):
WebElement常用屬性:
屬性 | 屬性描述 |
---|---|
size | 高和寬 |
rect | 高、寬和xy坐標(biāo) |
tag_name | 標(biāo)簽名稱(chēng) |
text | 文本內(nèi)容 |
WebElement常用方法:
屬性 | 屬性描述 |
---|---|
send_keys() | 輸入內(nèi)容(對(duì)同一個(gè)元素多次進(jìn)行,除非是頁(yè)面自有的邏輯,否則是按照追加的方式輸入的) |
clear() | 清空內(nèi)容 |
click() | 單擊,如果單擊后,當(dāng)前標(biāo)簽頁(yè)跳轉(zhuǎn)頁(yè)面時(shí),WebDriver對(duì)象會(huì)更新為當(dāng)前跳轉(zhuǎn)后的頁(yè)面,如果是新標(biāo)簽頁(yè)打開(kāi)其他頁(yè)面時(shí),WebDriver對(duì)象還是在原標(biāo)簽頁(yè),不會(huì)更新為新標(biāo)簽頁(yè) |
get_attribute() | 獲得屬性值 |
is_selected() | 是否被選中 |
is_enabled() | 是否可用 |
is_displayed() | 是否顯示 |
實(shí)例:
import time from selenium import webdriver from selenium.webdriver.common.by import By if __name__ == "__main__": # 定義一個(gè)WebDriver對(duì)象 driver = webdriver.Chrome() # 打開(kāi)百度首頁(yè) driver.get("https://www.baidu.com/") # 定位 搜索輸入框 search = driver.find_element(By.ID, "kw") # 在搜索輸入框中輸入“百度翻譯”,百度首頁(yè)會(huì)自動(dòng)搜索 search.send_keys("百度翻譯") time.sleep(3) # 清空搜索框的內(nèi)容 search.clear() time.sleep(3) # 定位 “百度首頁(yè)” more = driver.find_element(By.LINK_TEXT, "更多") print("”更多“的部分方法值:") print(f"get_attribute():{more.get_attribute('href')}") print(f"is_selected():{more.is_selected()}") print(f"is_enabled():{more.is_enabled()}") print(f"is_displayed():{more.is_displayed()}") print("\n“更多“的部分屬性值:") print(f"size值:{more.size}") print(f"rect值:{more.rect}") print(f"tag_name值:{more.tag_name}") print(f"text內(nèi)容:{more.text}") # 點(diǎn)擊”更多“ more.click() time.sleep(3) # 終止相關(guān)進(jìn)程 driver.quit()
等待
在打開(kāi)網(wǎng)頁(yè)時(shí),某些內(nèi)容會(huì)立馬顯示,但是有些內(nèi)容顯示的又比較慢,當(dāng)網(wǎng)速卡的時(shí)候,頁(yè)面就更慢顯示了,但是程序執(zhí)行的速度又是非??斓?,就會(huì)導(dǎo)致一個(gè)問(wèn)題:頁(yè)面元素還在加載中,程序(代碼)就去定位元素了,導(dǎo)致程序定位失敗、退出執(zhí)行。
為了避免這種情況發(fā)生,我們?cè)诙ㄎ辉厍?,就設(shè)置一定的延遲時(shí)間,盡量讓相關(guān)元素顯示后再去定位元素,可以有效的降低程序失敗的情況發(fā)生。
有3種等待方式:
- 直接等待:time.sleep(秒數(shù)),即直接等待指定的秒數(shù)再執(zhí)行后續(xù)語(yǔ)句,不夠靈活
- 隱式等待:WebDriver().implicitly_wait(秒數(shù)),每0.5秒輪詢(xún)查找元素,如果在指定的時(shí)間內(nèi)找到了元素,則繼續(xù)執(zhí)行,如果沒(méi)有找到,則報(bào)錯(cuò),是針對(duì)該WebDriver對(duì)象的find_element()和find_elements(),相當(dāng)于全局的,沒(méi)有對(duì)元素的“個(gè)性化”,不太建議使用
- 顯示等待:
直接等待
直接等待,也叫強(qiáng)制等待,就是必須等待指定的時(shí)間,才執(zhí)行下一步。需要導(dǎo)入time
,使用time.sleep(秒數(shù))
。除非頁(yè)面特有的邏輯(比如非會(huì)員必須觀看30秒廣告等),否則不建議大量使用time.sleep()方法。
示例:
import time from selenium import webdriver from selenium.webdriver.common.by import By if __name__ == "__main__": # 定義一個(gè)WebDriver對(duì)象 driver = webdriver.Chrome() # 打開(kāi)百度首頁(yè) driver.get("https://www.baidu.com/") # 直接等待2秒 time.sleep(2) # 點(diǎn)擊更多,跳轉(zhuǎn)到百度應(yīng)用列表頁(yè)面 driver.find_element(By.LINK_TEXT, "更多").click() #等待2秒后,關(guān)閉瀏覽器進(jìn)程 time.sleep(2) driver.quit()
隱式等待
隱式等待是在WebDriver對(duì)象上設(shè)置并生效的,當(dāng)WebDriver對(duì)象通過(guò)implicitly_wait(秒數(shù))
方法設(shè)置了隱式等待的時(shí)間后,通過(guò)當(dāng)前WebDriver對(duì)象使用的find_element()
和find_elements()
方法時(shí),會(huì)每個(gè)一段時(shí)間(0.5秒)去頁(yè)面查找,查找到后直接進(jìn)行下一步,沒(méi)有查找到則繼續(xù)查詢(xún),若超過(guò)了設(shè)置的等待時(shí)間還沒(méi)找到對(duì)應(yīng)的元素,則直接報(bào)錯(cuò)。
隱式等待相當(dāng)于全局性的,即WebDriver對(duì)象一次設(shè)置,對(duì)其調(diào)用的find_element()
和find_elements()
方法都生效。
隱式等待的時(shí)間設(shè)置比較方便,但是對(duì)于某些場(chǎng)景又不合適,設(shè)置的等待時(shí)間需要考慮到所有用到元素的最大的等待時(shí)間,但是一個(gè)頁(yè)面中,不同的功能所需的時(shí)間又不一樣,比如上傳\下載文件和頁(yè)面元素加載所花費(fèi)的時(shí)間顯然時(shí)不在同一個(gè)階段的(比如上傳完一個(gè)大容量視頻后的視頻上傳成功提示元素和只是單純?cè)陧?yè)面顯示文字,顯然后者能很快顯示),隱式時(shí)間設(shè)置過(guò)長(zhǎng)時(shí),若被測(cè)產(chǎn)品運(yùn)行有問(wèn)題,會(huì)導(dǎo)致執(zhí)行時(shí)間的拉長(zhǎng),不利于自動(dòng)化等的批量執(zhí)行和總體分析。
示例:
from selenium import webdriver from selenium.webdriver.common.by import By if __name__ == "__main__": # 定義一個(gè)WebDriver對(duì)象 driver = webdriver.Chrome() # 打開(kāi)百度首頁(yè) driver.get("https://www.baidu.com/") # 設(shè)置隱式等待的時(shí)間 driver.implicitly_wait(12) # 在搜索輸入框中輸入“一人之下” driver.find_element(By.ID, "kw").send_keys("一人之下") # 點(diǎn)擊搜索頁(yè)中,搜索輸入框左側(cè)的百度圖標(biāo)回到百度首頁(yè) driver.find_element(By.ID, "result_logo").click() # 關(guān)閉瀏覽器進(jìn)程 driver.quit()
顯示等待
顯示等待與隱式等待正好相反,顯示等待是針對(duì)某一個(gè)元素的,不是全局性質(zhì)的,當(dāng)然,定位元素過(guò)多的時(shí)候,又覺(jué)得一次性設(shè)置的隱式等待很香O(∩_∩)O。
顯示等待使用的是WebDriverWait
對(duì)象的until()
和until_not()
方法(可以說(shuō)是WebDriverWait
的左右護(hù)法了)
顯示等待中,等待的時(shí)間設(shè)置是在創(chuàng)建WebDriverWait對(duì)象時(shí):
WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)
參數(shù)說(shuō)明:
driver:WebDriver對(duì)象
- timeout:等待時(shí)間,即超時(shí)時(shí)間,如果在指定時(shí)間內(nèi)沒(méi)有找到,則報(bào)錯(cuò)
- poll_frequency:輪詢(xún)查找的時(shí)間,單位為秒,默認(rèn)0.5秒
WebDriverWait對(duì)象的until()和until_not()方法則用來(lái)判斷是否繼續(xù)執(zhí)行
until(method, message="")和until_not(method, message="")
參數(shù)說(shuō)明:
- method:函數(shù)名(函數(shù)必須要有一個(gè)參數(shù))
- until():如果函數(shù)執(zhí)行返回的是False(或0或None或空列表、空集合等等所有不為真的數(shù)據(jù)),則TimeoutException報(bào)錯(cuò),若返回的數(shù)據(jù)為真,則執(zhí)行下一句
- until_not():與until()相反,若函數(shù)返回為真的數(shù)據(jù),則TimeoutException報(bào)錯(cuò),若函數(shù)返回不為真的數(shù)據(jù),則執(zhí)行下一句
- message:若函數(shù)執(zhí)行返回了不為真的數(shù)據(jù),則TimeoutException報(bào)錯(cuò)時(shí),報(bào)錯(cuò)信息為message
until()的示例:
from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait if __name__ == "__main__": # 定義一個(gè)WebDriver對(duì)象 driver = webdriver.Chrome() def fun1(x): return True def fun2(x): return False wd = WebDriverWait(driver, 3) wd.until(fun1, "方法fun1返回了假") print("fun1執(zhí)行完成,找到元素") wd.until(fun2, "方法fun2返回了假") print("fun2執(zhí)行完成,找到元素") # 終止相關(guān)進(jìn)程 driver.quit()
執(zhí)行結(jié)果如下:
fun1執(zhí)行完成,找到元素
Traceback (most recent call last):
File "G:\python_project\web\demo.py", line 14, in <module>
wd.until(fun2, "方法fun2返回了假")
File "G:\python_project\web\lib\site-packages\selenium\webdriver\support\wait.py", line 95, in until
raise TimeoutException(message, screen, stacktrace)
selenium.common.exceptions.TimeoutException: Message: 方法fun2返回了假
從執(zhí)行結(jié)果來(lái)看,程序并沒(méi)有執(zhí)行到print("fun2執(zhí)行完成,找到元素")
,wd.until(fun2, "方法fun2返回了假")
這一步報(bào)錯(cuò)了,并打印了我們傳入的message內(nèi)容
until_not()示例
from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait if __name__ == "__main__": # 定義一個(gè)WebDriver對(duì)象 driver = webdriver.Chrome() def fun1(x): return True def fun2(x): return False wd = WebDriverWait(driver, 3) wd.until_not(fun2, "方法fun2返回了真") print("fun2執(zhí)行完成,找到元素") wd.until_not(fun1, "方法fun1返回了真") print("fun1執(zhí)行完成,找到元素") # 終止相關(guān)進(jìn)程 driver.quit()
執(zhí)行結(jié)果如下:
fun2執(zhí)行完成,找到元素
Traceback (most recent call last):
File "G:\python_project\web\demo.py", line 14, in <module>
wd.until_not(fun1, "方法fun1返回了真")
File "G:\python_project\web\lib\site-packages\selenium\webdriver\support\wait.py", line 118, in until_not
raise TimeoutException(message)
selenium.common.exceptions.TimeoutException: Message: 方法fun1返回了真
從以上2個(gè)示例來(lái)看,如果想要做到顯示等待某個(gè)元素,我們需要在until()
和until_not()
中傳入method參數(shù)來(lái)實(shí)現(xiàn),method參數(shù)傳入的是函數(shù),函數(shù)中需要實(shí)現(xiàn)對(duì)元素是否存在的判斷,示例如下:
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.wait import WebDriverWait if __name__ == "__main__": # 定義一個(gè)WebDriver對(duì)象 driver = webdriver.Chrome() # 打開(kāi)百度翻譯頁(yè)面,翻譯triggered driver.get("https://fanyi.baidu.com/#en/zh/triggered") def show_banner(x): # 只有在有翻譯的時(shí)候才會(huì)顯示廣告位 return len(driver.find_elements(By.CLASS_NAME, "app-side-banner")) > 0 wd = WebDriverWait(driver, 3) wd.until(show_banner, "未顯示廣告位") print("顯示了廣告位") # 終止相關(guān)進(jìn)程 driver.quit()
show_banner(x)實(shí)現(xiàn)了判斷某個(gè)元素存不存在邏輯,until()方法傳入了show_banner函數(shù),相當(dāng)于在3秒內(nèi)查詢(xún)?cè)撛卮娌淮嬖?,不存在則報(bào)錯(cuò),執(zhí)行結(jié)果如下:
顯示了廣告位
從執(zhí)行結(jié)果來(lái)看,確實(shí)顯示了廣告位
但是如果每一個(gè)元素都需要實(shí)現(xiàn)一個(gè)函數(shù)(或者使用匿名函數(shù)),豈不是很麻煩,所以selenium也提供了一系列元素判斷方法,這些方法封裝在了expected_conditions中,使用示例如下:
import time from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions if __name__ == "__main__": # 定義一個(gè)WebDriver對(duì)象 driver = webdriver.Chrome() # 打開(kāi)百度翻譯頁(yè)面 driver.get("https://fanyi.baidu.com/#en/zh") # 首次打開(kāi)百度翻譯頁(yè)面,有百度翻譯的引導(dǎo)彈窗,等待彈窗顯示后,關(guān)閉該彈窗 # 確定引導(dǎo)彈窗顯示 WebDriverWait(driver, 4).until(expected_conditions.element_to_be_clickable((By.CLASS_NAME, "app-guide-close"))) # 點(diǎn)擊引導(dǎo)彈窗的關(guān)閉按鈕,關(guān)閉引導(dǎo)彈窗 driver.find_element(By.CLASS_NAME, "app-guide-close").click() # 為了確認(rèn)是否關(guān)閉了引導(dǎo)彈窗,強(qiáng)制等待3秒查看效果(人眼查看) time.sleep(3) # 使用expected_conditions下的visibility_of_element_located()判斷廣告位是否不存在,不存在返回True banner_show = expected_conditions.visibility_of_element_located((By.CLASS_NAME, "app-side-banner")) print("廣告位不存在" if banner_show else "廣告位存在") # 終止相關(guān)進(jìn)程 driver.quit()
執(zhí)行結(jié)果如下:
廣告位不存在
expected_conditions
有提供了很多方法,基本上從方法名可以判斷出來(lái),詳細(xì)的可以網(wǎng)上找找,這里不詳細(xì)展開(kāi)了,可以去selenium官網(wǎng)查看,也可以參考的一些博客,如下:
selenium自動(dòng)化測(cè)試(八)-- expected_conditions詳解
selenium中的expected_conditions模塊詳解
selenium細(xì)節(jié)實(shí)戰(zhàn)02–>好用的expected_conditions模塊
等待說(shuō)明
三種等待方式可以混合使用,雖然expected_conditions的諸多方法底層其實(shí)是調(diào)用了find_element()方法,但implicitly_wait()和WebDriverWait()一起使用時(shí),等待時(shí)間是兩者間設(shè)置時(shí)長(zhǎng)最長(zhǎng)的那個(gè)(貌似說(shuō)不能混合使用,但是我混了后還沒(méi)報(bào)錯(cuò)。。。暫時(shí)就先不管了)
到此這篇關(guān)于python中的selenium入門(mén)教程的文章就介紹到這了,更多相關(guān)python selenium入門(mén)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python 基于wx實(shí)現(xiàn)音樂(lè)播放
這篇文章主要介紹了python 基于wx實(shí)現(xiàn)音樂(lè)播放的示例代碼,幫助大家更好的理解和學(xué)習(xí)python,感興趣的朋友可以了解下2020-11-11Python 專(zhuān)題六 局部變量、全局變量global、導(dǎo)入模塊變量
本文主要講述python全局變量、局部變量和導(dǎo)入模塊變量的方法。具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧2017-03-03用Python展示動(dòng)態(tài)規(guī)則法用以解決重疊子問(wèn)題的示例
這篇文章主要介紹了用Python展示動(dòng)態(tài)規(guī)則法用以解決重疊子問(wèn)題的一個(gè)棋盤(pán)游戲的示例,動(dòng)態(tài)規(guī)劃常常適用于有重疊子問(wèn)題和最優(yōu)子結(jié)構(gòu)性質(zhì)的問(wèn)題,且耗時(shí)間往往遠(yuǎn)少于樸素解法,需要的朋友可以參考下2015-04-04Python代碼執(zhí)行時(shí)間測(cè)量模塊timeit用法解析
這篇文章主要介紹了Python代碼執(zhí)行時(shí)間測(cè)量模塊timeit用法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07python反射機(jī)制內(nèi)置函數(shù)及場(chǎng)景構(gòu)造詳解
這篇文章主要為大家介紹了python反射機(jī)制內(nèi)置函數(shù)及場(chǎng)景構(gòu)造示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11python實(shí)現(xiàn)拓?fù)渑判虻姆椒ú襟E
拓?fù)渑判蚴菍?duì)有向無(wú)環(huán)圖進(jìn)行排序的一種算法,本文主要介紹了python實(shí)現(xiàn)拓?fù)渑判虻姆椒ú襟E,具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03tensorflow2 自定義損失函數(shù)使用的隱藏坑
本文主要介紹了tensorflow2 自定義損失函數(shù)使用的隱藏坑,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-07-07