一、selenium簡(jiǎn)介
1、介紹
Selenium是一個(gè)用于Web應(yīng)用程序測(cè)試的工具。Selenium測(cè)試直接運(yùn)行在瀏覽器中,就像真正的用戶(hù)在操作一樣。支持的瀏覽器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等。這個(gè)工具的主要功能包括:測(cè)試與瀏覽器的兼容性——測(cè)試你的應(yīng)用程序看是否能夠很好得工作在不同瀏覽器和操作系統(tǒng)之上。測(cè)試系統(tǒng)功能——?jiǎng)?chuàng)建回歸測(cè)試檢驗(yàn)軟件功能和用戶(hù)需求。支持自動(dòng)錄制動(dòng)作和自動(dòng)生成 .Net、Java、Perl等不同語(yǔ)言的測(cè)試腳本。
2、功能
1.框架底層使用JavaScript模擬真實(shí)用戶(hù)對(duì)瀏覽器進(jìn)行操作。測(cè)試腳本執(zhí)行時(shí),瀏覽器自動(dòng)按照腳本代碼做出點(diǎn)擊,輸入,打開(kāi),驗(yàn)證等操作,就像真實(shí)用戶(hù)所做的一樣,從終端用戶(hù)的角度測(cè)試應(yīng)用程序。
2.使瀏覽器兼容性測(cè)試自動(dòng)化成為可能,盡管在不同的瀏覽器上依然有細(xì)微的差別。
3.使用簡(jiǎn)單,可使用Java,Python等多種語(yǔ)言編寫(xiě)用例腳本。
3、優(yōu)勢(shì)
Selenium 測(cè)試直接在瀏覽器中運(yùn)行,就像真實(shí)用戶(hù)所做的一樣。Selenium 測(cè)試可以在 Windows、Linux 和 Macintosh上的 Internet Explorer、Chrome和 Firefox 中運(yùn)行。其他測(cè)試工具都不能覆蓋如此多的平臺(tái)。使用 Selenium 和在瀏覽器中運(yùn)行測(cè)試還有很多其他好處。
主要的兩大好處:
通過(guò)編寫(xiě)模仿用戶(hù)操作的 Selenium 測(cè)試腳本,可以從終端用戶(hù)的角度來(lái)測(cè)試應(yīng)用程序。通過(guò)在不同瀏覽器中運(yùn)行測(cè)試,更容易發(fā)現(xiàn)瀏覽器的不兼容性。Selenium 的核心,也稱(chēng) browser bot,是用 JavaScript 編寫(xiě)的。這使得測(cè)試腳本可以在受支持的瀏覽器中運(yùn)行。browser bot 負(fù)責(zé)執(zhí)行從測(cè)試腳本接收到的命令,測(cè)試腳本要么是用 HTML 的表布局編寫(xiě)的,要么是使用一種受支持的編程語(yǔ)言編寫(xiě)的。
二、基本使用
安裝: pip install selenium
from selenium import webdriver? browser = webdriver.Chrome(executable_path='chromedriver.exe')? # 聲明一個(gè)瀏覽器對(duì)象? 指定使用chromedriver.exe路徑? browser.get("https://www.baidu.com")? # 打開(kāi)Chrome input = browser.find_element_by_id("kw")? # 通過(guò)id定位到input框 input.send_keys("python")? # 在輸入框內(nèi)輸入python? print(browser.current_url)? ? # 打印url print(browser.get_cookies())? # 打印Cookies print(browser.page_source)? ? # 打印網(wǎng)頁(yè)源代碼? browser.close()? ? ? ? ? ? ? # 關(guān)閉瀏覽器
三、獲取單節(jié)點(diǎn)
from selenium import webdriver? browser = webdriver.Chrome()? browser.get("https://www.taobao.com") # 找到搜索框 input_id = browser.find_element_by_id("q")? # 通過(guò)id找 input_name = browser.find_element_by_name("q")? # 通過(guò)name屬性值找 input_css = browser.find_element_by_css_selector("#q") # 根據(jù)css選擇器找 input_xpath = browser.find_element_by_xpath('//*[@id="q"]') # 根據(jù)xpath找 print(input_id,input_name,input_css,input_xpath) browser.close() """ <selenium.webdriver.remote.webelement.WebElement (session="1dfb3c1ac919b0a5ff778cd3bf6db759", element="84b6d58e-04d6-4483-9a3f-f2e116437075")>? <selenium.webdriver.remote.webelement.WebElement (session="1dfb3c1ac919b0a5ff778cd3bf6db759", element="84b6d58e-04d6-4483-9a3f-f2e116437075")>? <selenium.webdriver.remote.webelement.WebElement (session="1dfb3c1ac919b0a5ff778cd3bf6db759", element="84b6d58e-04d6-4483-9a3f-f2e116437075")>? <selenium.webdriver.remote.webelement.WebElement (session="1dfb3c1ac919b0a5ff778cd3bf6db759", element="84b6d58e-04d6-4483-9a3f-f2e116437075")> """? # 其他獲取單個(gè)節(jié)點(diǎn)方法 """ find_element_by_link_text find_element_by_partial_link_text find_element_by_tag_name find_element_by_class_name """ # 通過(guò)方法 # find_element(By.ID,"q")? # 參數(shù)為查找方式和值
四、獲取多節(jié)點(diǎn)
from selenium import webdriver? browser = webdriver.Chrome()? browser.get("https://www.taobao.com")? lis = browser.find_elements_by_css_selector(".service-bd li")? # 注意是elements多個(gè)s print(lis)? # 輸出為列表? """ [<selenium.webdriver.remote.webelement.WebElement (session="588f61b0d90f7bf199d3f0ede6f9fb99", element="454d656c-1730-410e-891e-210bfdf0d248")>, <selenium.webdriver.remote.webelement.WebElement (session="588f61b0d90f7bf199d3f0ede6f9fb99", element="119177aa-014a-48c1-8bea-8ca9a50b446e")>, <selenium.webdriver.remote.webelement.WebElement (session="588f61b0d90f7bf199d3f0ede6f9fb99", element="974860cf-1218-4ddf-a745-85f86090e188")>, <selenium.webdriver.remote.webelement.WebElement (session="588f61b0d90f7bf199d3f0ede6f9fb99", element="e5877c0c-f4df-4847-9875-1c81d56f21ee")>] """? # 其他獲取多個(gè)節(jié)點(diǎn)方法 """ find_elements_by_id("q") find_elements_by_name("q") find_elements_by_css_selector("#q") find_elements_by_xpath('//*[@id="q"]') find_elements_by_link_text find_elements_by_partial_link_text find_elements_by_tag_name find_elements_by_class_name """ # 通過(guò)方法 # find_elements(By.CSS_SELECTOR,".service-bd li")? # 參數(shù)為查找方式和值
五、節(jié)點(diǎn)交互
import time from selenium import webdriver? browser = webdriver.Chrome()? browser.get("https://www.taobao.com")? """ selenium可以驅(qū)動(dòng)瀏覽器來(lái)執(zhí)行一些動(dòng)作: 輸入文字用send_keys() 清空文字用clear() 點(diǎn)擊按鈕用click() """? input = browser.find_element_by_id("q") input.send_keys("iPhone")? #在搜索框輸入iPhone? input.clear()? # 清空搜索框的文字 time.sleep(2) input.send_keys("iPad")? # 在搜索框輸入iPad? button = browser.find_element_by_class_name("btn-search")? # 獲取點(diǎn)擊按鈕 button.click()? # 點(diǎn)擊搜索
六、動(dòng)作鏈
from selenium import webdriver from selenium.webdriver import ActionChains? # 引入動(dòng)作鏈 browser = webdriver.Chrome() url = "https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable" browser.get(url)? browser.switch_to.frame("iframeResult")? # 切換到元素所在的frame[框架] """ 可以傳入id、name、index以及selenium的WebElement對(duì)象,index從0開(kāi)始 """? source = browser.find_element_by_css_selector("#draggable") # 找到被拖拽對(duì)象 target = browser.find_element_by_css_selector("#droppable") # 找到目標(biāo)? actions = ActionChains(browser)? ? ? # 聲明actions對(duì)象 actions.drag_and_drop(source,target)? # 拖拽元素的起點(diǎn)和終點(diǎn) actions.perform()? # 執(zhí)行動(dòng)作? action.click_and_hold()? ? # 點(diǎn)擊且長(zhǎng)按,更多方法查看官方文檔
七、執(zhí)行JavaScript代碼
from selenium import webdriver? browser = webdriver.Chrome() url = "https://www.zhihu.com/explore" browser.get(url)? browser.execute_script("window.scrollTo(0,document.body.scrollHeight)") # 將進(jìn)度條下拉到最底部 browser.execute_script("alert('hello word')")? # 彈出alert提示窗
八、獲取節(jié)點(diǎn)信息
from selenium import webdriver browser = webdriver.Chrome()? url = "https://www.zhihu.com/explore"? browser.get(url)? """ WebElement常用屬性:? ? get_attribute 獲取屬性值? ? text? ? ? ? ? 獲取文本值? ? id? ? ? ? ? ? 獲取節(jié)點(diǎn)id? ? location? ? ? 獲取節(jié)點(diǎn)在頁(yè)面中的相對(duì)位置? ? tag_name? ? ? 獲取標(biāo)簽名稱(chēng)? ? size? ? ? ? ? 獲取節(jié)點(diǎn)大小(寬和高) """? # 獲取屬性 logo = browser.find_element_by_id("zh-top-link-logo")? # 獲取logo節(jié)點(diǎn) print(logo)? # 返回值為WebElement對(duì)象? logo_class = logo.get_attribute("class")? # 獲取zh-top-link-logo節(jié)點(diǎn)的class屬性值 print(logo_class)? # 獲取文本值 text_Ele = browser.find_element_by_css_selector(".question_link") # 通過(guò)css選擇器獲取文本內(nèi)容所在的標(biāo)簽 text = text_Ele.text? # 取出標(biāo)簽內(nèi)的文本內(nèi)容 print(text)? # 獲取ID 位置 標(biāo)簽名和大小 test = browser.find_element_by_class_name("zu-top-add-question") print(test.id)? ? ? # 0bfe7ae6-ebd9-499a-8f4e-35ae34776687 print(test.location) # {'x': 759, 'y': 7} print(test.tag_name) # button print(test.size)? ? # {'height': 32, 'width': 66}
九、切換frame
from selenium import webdriver? browser = webdriver.Chrome()? url = "https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable"? browser.get(url) """ 網(wǎng)頁(yè)中有一種節(jié)點(diǎn)叫做iframe,也就是子Frame,相當(dāng)于頁(yè)面的子頁(yè)面, 他的結(jié)構(gòu)和外部網(wǎng)頁(yè)的結(jié)構(gòu)完全一致。 selenium打開(kāi)頁(yè)面后,他默認(rèn)是在父級(jí)Frame里面操作, 而此時(shí)如果頁(yè)面中還有子Frame,他是不能獲取到子Frame里面的節(jié)點(diǎn)的, 這時(shí)候就需要使用switch_to.frame()方法來(lái)切換Frame。 """ browser.switch_to.frame("iframeResult") logo = browser.find_elements_by_class_name("logo") print(logo)? # [<selenium.webdriver.remote.webelement.WebElement (session="1ccb11403013c749ce9fceda50a00975", element="88e5924e-d655-44c3-a905-8af1947b9d86")>]
十、延時(shí)等待
---------------------------隱式等待------------------------- from selenium import webdriver? browser = webdriver.Chrome() # 隱式等待 browser.implicitly_wait(2) # 設(shè)定等待時(shí)間? url = "https://www.zhihu.com/explore" browser.get(url) input = browser.find_element_by_class_name("aaa") print(input) # 報(bào)錯(cuò)信息 """? raise exception_class(message, screen, stacktrace) selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":".aaa"}? (Session info: chrome=75.0.3770.142) """? """ 如果selenium沒(méi)有在DOM中找到節(jié)點(diǎn),將繼續(xù)等待,超出設(shè)定事件后,則拋出找不到節(jié)點(diǎn)的異常。 當(dāng)查找節(jié)點(diǎn)而節(jié)點(diǎn)并沒(méi)有立即出現(xiàn)的時(shí)候,隱式等待將等待一段時(shí)間在查找DOM,默認(rèn)時(shí)間是0 """? --------------------------顯式等待------------------------ # 顯示等待 from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC? browser = webdriver.Chrome() browser.get("https://www.taobao.com/") wait = WebDriverWait(browser,2)? input = wait.until(EC.presence_of_element_located((By.ID,"q"))) button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,".btn-search"))) print(input,button)? # 等待條件 # EC.presence_of_element_located? 節(jié)點(diǎn)出現(xiàn) # EC.element_to_be_clickable? ? ? 可點(diǎn)擊 # 更多等待條件查看260頁(yè)? """ 引入WebDriverWait對(duì)象指定最長(zhǎng)等待時(shí)間,調(diào)用它的until方法, 傳入要等待的條件expected_conditions,比如這里傳入例如presence_of_element_located 這個(gè)條件,代表節(jié)點(diǎn)出現(xiàn)的意思,其參數(shù)是節(jié)點(diǎn)的定位元組,也就是ID為q的搜索框。 這樣可以做到的效果就是,在10秒內(nèi)如果ID為q的節(jié)點(diǎn)(即搜索框)成功加載出來(lái),就返回該節(jié)點(diǎn), 如果10秒還沒(méi)有加載出來(lái),就拋出異常。 """? """ 異常: TimeoutException """? """ 指定要查找的節(jié)點(diǎn),然后指定一個(gè)最長(zhǎng)等待時(shí)間,如果在規(guī)定時(shí)間內(nèi)加載出來(lái)了這個(gè)節(jié)點(diǎn), 就返回查找的節(jié)點(diǎn),如果到了規(guī)定時(shí)間依然沒(méi)有加載出該節(jié)點(diǎn),則拋出【超時(shí)】異常 """
十一、前進(jìn)和后退
import time? from selenium import webdriver? browser = webdriver.Chrome() browser.get("https://www.baidu.com") browser.get("https://www.taobao.com") browser.get("https://www.jd.com")? browser.back()? # 后退 time.sleep(2) browser.forward() # 前進(jìn) browser.close()? # 關(guān)閉瀏覽器? # 連續(xù)訪(fǎng)問(wèn)三個(gè)頁(yè)面
十二、cookies
from selenium import webdriver? browser = webdriver.Chrome()? browser.get("https://www.zhihu.com/explore") cookies = browser.get_cookies()? # 獲取cookies print(cookies)? browser.add_cookie({"name":"name","domain":"www.zhihu.com","vlue":"germey"})? browser.delete_all_cookies()? # 刪除所有cookies
十三、選項(xiàng)卡管理
import time from selenium import webdriver? browser = webdriver.Chrome()? browser.get("https://www.baidu.com") browser.execute_script("window.open()") print(browser.window_handles) # ['CDwindow-7106D94FF002752ADF198B986343E31D', 'CDwindow-B669BA9559DBB78D8D6EC9C5AA699C40']? browser.switch_to.window(browser.window_handles[1]) browser.get("https://www.taobao.com") time.sleep(1)? browser.switch_to.window(browser.window_handles[0]) browser.get("https://jd.com")? """ 1、打開(kāi)百度網(wǎng)頁(yè) 2、新開(kāi)一個(gè)選項(xiàng)卡,調(diào)用execute_script()方法傳入JavaScript語(yǔ)法window.open() 3、切換到新打開(kāi)的選項(xiàng)卡,調(diào)用window_handles屬性獲取當(dāng)前開(kāi)啟的所有選項(xiàng)卡,返回的是選項(xiàng)卡的代號(hào)列表, 要想切換選項(xiàng)卡只需要調(diào)用switch_to.window()方法,這里我們將第二個(gè)選項(xiàng)卡代號(hào)傳入, 即跳轉(zhuǎn)到第二個(gè)選項(xiàng)卡,在第二個(gè)選項(xiàng)卡里打開(kāi)新頁(yè)面https://www.taobao.com,然后切換回第一個(gè)選項(xiàng)卡打開(kāi)jd頁(yè)面 """
十四、異常處理
from selenium import webdriver? browser = webdriver.Chrome() browser.get("https://www.baidu.com") try:? ? browser.find_element_by_id("hello") except Exception as e:? ? print(e)? # 打印錯(cuò)誤信息 Exception捕獲所有錯(cuò)誤信息賦給e finally:? ? browser.close()? """ 在使用selenium的過(guò)程中,難免遇到一些異常,例如超時(shí)、節(jié)點(diǎn)未找到錯(cuò)誤, 一旦出現(xiàn)此類(lèi)錯(cuò)誤,程序便不會(huì)在繼續(xù)運(yùn)行了,這里我們使用try except語(yǔ)句來(lái)捕獲各種異常 """
十五、無(wú)頭瀏覽器
from selenium import webdriver
from selenium.webdriver.chrome.options import Options?
# 創(chuàng)建chrome參數(shù)對(duì)象
opt = Options()
# 把chrome設(shè)置成無(wú)界面模式,不論windows還是linux都可以,自動(dòng)適配對(duì)應(yīng)參數(shù) opt.add_argument('--headless')
# 創(chuàng)建chrome無(wú)界面對(duì)象
driver = webdriver.Chrome(options=opt)
driver.get("http://www.baidu.com")
print(driver.page_source)