selenium簡介
介紹
Selenium [1] 是一個用於Web應用程序測試的工具。Selenium測試直接運行在瀏覽器中,就像真正的用戶在操作一樣。支持的瀏覽器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等。這個工具的主要功能包括:測試與瀏覽器的兼容性——測試你的應用程序看是否能夠很好得工作在不同瀏覽器和操作系統之上。測試系統功能——創建回歸測試檢驗軟件功能和用戶需求。支持自動錄制動作和自動生成 .Net、Java、Perl等不同語言的測試腳本。
功能
-
框架底層使用JavaScript模擬真實用戶對瀏覽器進行操作。測試腳本執行時,瀏覽器自動按照腳本代碼做出點擊,輸入,打開,驗證等操作,就像真實用戶所做的一樣,從終端用戶的角度測試應用程序。
-
使瀏覽器兼容性測試自動化成為可能,盡管在不同的瀏覽器上依然有細微的差別。
-
使用簡單,可使用Java,Python等多種語言編寫用例腳本。
優勢
Selenium 測試直接在瀏覽器中運行,就像真實用戶所做的一樣。Selenium 測試可以在 Windows、Linux 和 Macintosh上的 Internet Explorer、Chrome和 Firefox 中運行。其他測試工具都不能覆蓋如此多的平台。使用 Selenium 和在瀏覽器中運行測試還有很多其他好處。
下面是主要的兩大好處:
通過編寫模仿用戶操作的 Selenium 測試腳本,可以從終端用戶的角度來測試應用程序。通過在不同瀏覽器中運行測試,更容易發現瀏覽器的不兼容性。Selenium 的核心,也稱
browser bot,是用 JavaScript 編寫的。這使得測試腳本可以在受支持的瀏覽器中運行。browser bot 負責執行從測試腳本接收到的命令,測試腳本要么是用 HTML 的表布局編寫的,要么是使用一種受支持的編程語言編寫的。
官方文檔:
https://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.common.action_chains
chromedriver下載:http://chromedriver.storage.googleapis.com/index.html
chromedriver與chrome的對應關系表:
https://www.jb51.net/article/151629.htm
基本使用
安裝: pip install selenium
from selenium import webdriver browser = webdriver.Chrome(executable_path='chromedriver.exe') # 聲明一個瀏覽器對象 指定使用chromedriver.exe路徑 browser.get("https://www.baidu.com") # 打開Chrome input = browser.find_element_by_id("kw") # 通過id定位到input框 input.send_keys("python") # 在輸入框內輸入python print(browser.current_url) # 打印url print(browser.get_cookies()) # 打印Cookies print(browser.page_source) # 打印網頁源代碼 browser.close() # 關閉瀏覽器
獲取單節點
from selenium import webdriver browser = webdriver.Chrome() browser.get("https://www.taobao.com") # 找到搜索框 input_id = browser.find_element_by_id("q") # 通過id找 input_name = browser.find_element_by_name("q") # 通過name屬性值找 input_css = browser.find_element_by_css_selector("#q") # 根據css選擇器找 input_xpath = browser.find_element_by_xpath('//*[@id="q"]') # 根據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")> """ # 其他獲取單個節點方法 """ find_element_by_link_text find_element_by_partial_link_text find_element_by_tag_name find_element_by_class_name """ # 通過方法 # find_element(By.ID,"q") # 參數為查找方式和值
獲取多節點
from selenium import webdriver browser = webdriver.Chrome() browser.get("https://www.taobao.com") lis = browser.find_elements_by_css_selector(".service-bd li") # 注意是elements多個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")>] """ # 其他獲取多個節點方法 """ 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 """ # 通過方法 # find_elements(By.CSS_SELECTOR,".service-bd li") # 參數為查找方式和值
節點交互
import time from selenium import webdriver browser = webdriver.Chrome() browser.get("https://www.taobao.com") """ selenium可以驅動瀏覽器來執行一些動作: 輸入文字用send_keys() 清空文字用clear() 點擊按鈕用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") # 獲取點擊按鈕 button.click() # 點擊搜索
動作鏈
from selenium import webdriver from selenium.webdriver import ActionChains # 引入動作鏈 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對象,index從0開始 """ source = browser.find_element_by_css_selector("#draggable") # 找到被拖拽對象 target = browser.find_element_by_css_selector("#droppable") # 找到目標 actions = ActionChains(browser) # 聲明actions對象 actions.drag_and_drop(source,target) # 拖拽元素的起點和終點 actions.perform() # 執行動作
action.click_and_hold() # 點擊且長按,更多方法查看官方文檔
執行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)") # 將進度條下拉到最底部 browser.execute_script("alert('hello word')") # 彈出alert提示窗
獲取節點信息
from selenium import webdriver browser = webdriver.Chrome() url = "https://www.zhihu.com/explore" browser.get(url) """ WebElement常用屬性: get_attribute 獲取屬性值 text 獲取文本值 id 獲取節點id location 獲取節點在頁面中的相對位置 tag_name 獲取標簽名稱 size 獲取節點大小(寬和高) """ # 獲取屬性 logo = browser.find_element_by_id("zh-top-link-logo") # 獲取logo節點 print(logo) # 返回值為WebElement對象 logo_class = logo.get_attribute("class") # 獲取zh-top-link-logo節點的class屬性值 print(logo_class) # 獲取文本值 text_Ele = browser.find_element_by_css_selector(".question_link") # 通過css選擇器獲取文本內容所在的標簽 text = text_Ele.text # 取出標簽內的文本內容 print(text) # 獲取ID 位置 標簽名和大小 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) """ 網頁中有一種節點叫做iframe,也就是子Frame,相當於頁面的子頁面, 他的結構和外部網頁的結構完全一致。 selenium打開頁面后,他默認是在父級Frame里面操作, 而此時如果頁面中還有子Frame,他是不能獲取到子Frame里面的節點的, 這時候就需要使用switch_to.frame()方法來切換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")>]
延時等待
---------------------------隱式等待------------------------- from selenium import webdriver browser = webdriver.Chrome() # 隱式等待 browser.implicitly_wait(2) # 設定等待時間 url = "https://www.zhihu.com/explore" browser.get(url) input = browser.find_element_by_class_name("aaa") print(input) # 報錯信息 """ 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沒有在DOM中找到節點,將繼續等待,超出設定事件后,則拋出找不到節點的異常。 當查找節點而節點並沒有立即出現的時候,隱式等待將等待一段時間在查找DOM,默認時間是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 節點出現 # EC.element_to_be_clickable 可點擊 # 更多等待條件查看260頁 """ 引入WebDriverWait對象指定最長等待時間,調用它的until方法, 傳入要等待的條件expected_conditions,比如這里傳入例如presence_of_element_located 這個條件,代表節點出現的意思,其參數是節點的定位元組,也就是ID為q的搜索框。 這樣可以做到的效果就是,在10秒內如果ID為q的節點(即搜索框)成功加載出來,就返回該節點, 如果10秒還沒有加載出來,就拋出異常。 """ """ 異常: TimeoutException """ """ 指定要查找的節點,然后指定一個最長等待時間,如果在規定時間內加載出來了這個節點, 就返回查找的節點,如果到了規定時間依然沒有加載出該節點,則拋出【超時】異常 """
前進和后退
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() # 前進 browser.close() # 關閉瀏覽器 # 連續訪問三個頁面
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
選項卡管理
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、打開百度網頁 2、新開一個選項卡,調用execute_script()方法傳入JavaScript語法window.open() 3、切換到新打開的選項卡,調用window_handles屬性獲取當前開啟的所有選項卡,返回的是選項卡的代號列表, 要想切換選項卡只需要調用switch_to.window()方法,這里我們將第二個選項卡代號傳入, 即跳轉到第二個選項卡,在第二個選項卡里打開新頁面https://www.taobao.com,然后切換回第一個選項卡打開jd頁面 """
異常處理
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) # 打印錯誤信息 Exception捕獲所有錯誤信息賦給e finally: browser.close() """ 在使用selenium的過程中,難免遇到一些異常,例如超時、節點未找到錯誤, 一旦出現此類錯誤,程序便不會在繼續運行了,這里我們使用try except語句來捕獲各種異常 """
選項卡切換
import time from selenium import webdriver from selenium.webdriver import ChromeOptions option = ChromeOptions() browser = webdriver.Chrome(executable_path='D:\chromedriver.exe',options=option) # 聲明一個瀏覽器對象 option.add_experimental_option('excludeSwitches', ['enable-automation']) browser.get("https://www.baidu.com") # 打開Chrome input = browser.find_element_by_id("kw") # 通過id定位到input框 input.send_keys("愛奇藝") # 在輸入框內輸入python browser.find_element_by_id("su").click() time.sleep(3) browser.find_element_by_xpath('//*[@id="1"]/h3').click() time.sleep(10) browser.switch_to_window(browser.window_handles[1]) # 切換到新打開的選項卡定位愛奇藝的搜索框 search = browser.find_element_by_xpath("//input[@class='search-box-input']").send_keys("青春有你") browser.close() # 關閉瀏覽器
無頭瀏覽器
from selenium import webdriver from selenium.webdriver.chrome.options import Options # 創建chrome參數對象 opt = Options() # 把chrome設置成無界面模式,不論windows還是linux都可以,自動適配對應參數 opt.add_argument('--headless') # 創建chrome無界面對象 driver = webdriver.Chrome(options=opt) driver.get("http://www.baidu.com") print(driver.page_source)