WebDriver API

WebDriver 屬於selenium體系中設計出來操做瀏覽器的一套API。css

在webdriver角度上,因他針對多種編程語言都實現了一遍這套API,因此他能夠支持多種編程語言;在編程語言的角度,webdriver是python的一個用於實現web自動化的第三方庫html

 

1、WebDriver 原理python

webdriver是按照server-client的設計模式設計的:web

  server端就是remote server,能夠是任意瀏覽器。當腳本啓動瀏覽器後,瀏覽器就是remote server,他的職責就是等待client發送請求並作出響應。ajax

  client是咱們的測試代碼了,代碼中的一些行爲(打開瀏覽器、跳轉URL等)操做是以http請求的方式發送給被測試瀏覽器的(remote server)。remote server接受請求,執行相應操做並在response中返回執行狀態、返回值等chrome

webdriver 工做流程:編程

  1.webdriver啓動瀏覽器,並綁定到指定的端口。啓動瀏覽器實例將做爲webdriver的remote server設計模式

  2.client端經過commandexcuter 發送httprequest給remote server的偵聽端口(通訊協議:the webriver wire protocol)
瀏覽器

  3.remote server須要依賴原聲的瀏覽器組件(如IEDriverServer.exe、chromedriver.exe)來轉化瀏覽器的native調用服務器

 

python提供了logging模塊給運行中的應用提供了一個標準的信息輸出接口:

from selenium import webdriver
import logging

logging.basicConfig(level=logging.DEBUG) #此模式能捕獲到客戶端向服務端發送的post請求
diver = webdriver.Ie()
diver.get("http://www.baidu.com")

diver.find_element_by_id("kw").send_keys("selenium")
diver.find_element_by_id("su").click()
diver.quit()


C:\Users\xiu\AppData\Local\Programs\Python\Python36-32\python.exe D:/study/besttest/XIU/logs/debug11.py
DEBUG:selenium.webdriver.remote.remote_connection:POST http://127.0.0.1:51379/session {"capabilities": {"firstMatch": [{}], "alwaysMatch": {"browserName": "internet explorer"}}, "desiredCapabilities": {"browserName": "internet explorer", "version": "", "platform": "WINDOWS"}}
DEBUG:selenium.webdriver.remote.remote_connection:Finished Request
DEBUG:selenium.webdriver.remote.remote_connection:POST http://127.0.0.1:51379/session/b13cead7-a113-4840-8a19-14b58ae3aaaf/url {"url": "http://www.baidu.com", "sessionId": "b13cead7-a113-4840-8a19-14b58ae3aaaf"}
DEBUG:selenium.webdriver.remote.remote_connection:Finished Request
DEBUG:selenium.webdriver.remote.remote_connection:POST http://127.0.0.1:51379/session/b13cead7-a113-4840-8a19-14b58ae3aaaf/element {"using": "id", "value": "kw", "sessionId": "b13cead7-a113-4840-8a19-14b58ae3aaaf"}
DEBUG:selenium.webdriver.remote.remote_connection:Finished Request
DEBUG:selenium.webdriver.remote.remote_connection:POST http://127.0.0.1:51379/session/b13cead7-a113-4840-8a19-14b58ae3aaaf/element/416ba0b6-a972-45c7-a25e-d37dfe5729c5/value {"text": "selenium", "value": ["s", "e", "l", "e", "n", "i", "u", "m"], "id": "416ba0b6-a972-45c7-a25e-d37dfe5729c5", "sessionId": "b13cead7-a113-4840-8a19-14b58ae3aaaf"}
DEBUG:selenium.webdriver.remote.remote_connection:Finished Request
DEBUG:selenium.webdriver.remote.remote_connection:POST http://127.0.0.1:51379/session/b13cead7-a113-4840-8a19-14b58ae3aaaf/element {"using": "id", "value": "su", "sessionId": "b13cead7-a113-4840-8a19-14b58ae3aaaf"}
DEBUG:selenium.webdriver.remote.remote_connection:Finished Request
DEBUG:selenium.webdriver.remote.remote_connection:POST http://127.0.0.1:51379/session/b13cead7-a113-4840-8a19-14b58ae3aaaf/element/5d135cb0-7222-4978-9d52-2950eca2b63e/click {"id": "5d135cb0-7222-4978-9d52-2950eca2b63e", "sessionId": "b13cead7-a113-4840-8a19-14b58ae3aaaf"}
DEBUG:selenium.webdriver.remote.remote_connection:Finished Request
DEBUG:selenium.webdriver.remote.remote_connection:DELETE http://127.0.0.1:51379/session/b13cead7-a113-4840-8a19-14b58ae3aaaf {"sessionId": "b13cead7-a113-4840-8a19-14b58ae3aaaf"}
DEBUG:selenium.webdriver.remote.remote_connection:Finished Request

Process finished with exit code 0

2、元素定位(id、name、class、tag、link、partial link、Xpath、CSS、By九種方法定位元素)

 

from selenium import webdriver
driver = webdriver.Ie()
driver.get('http://www.baidu.com')
# driver.find_element_by_id('kw').send_keys('selenium 自動化測試') #id定位
# driver.find_element_by_name('wd').clear() #name定位
# driver.find_element_by_class_name('s_ipt').send_keys('selenium') #class定位
# driver.find_element_by_tag_name('input').clear() #--tag定位。一個界面可能會有不少相同的tag,所以此定位方法識別某個元素的機率很低,通常不單獨用
# driver.find_element_by_link_text('新聞').click() #link定位
# driver.find_element_by_partial_link_text('《不忘初心 繼續前進》').click() #對link定位的一個補充,支持經過元素標籤之間的部分文本信息來定位
#xpath定位
# driver.find_element_by_xpath('/html/body/div[2]/div/div/div/div/form/span[1]/input').clear() #絕對路徑
# driver.find_element_by_xpath("//*[@id='kw']").send_keys('seleium2') #元素屬性定位
# driver.find_element_by_xpath("//*[@name='wd']").clear() #元素屬性定位
# driver.find_element_by_xpath("//*[@class='s_ipt']").send_keys('seleium3') #元素屬性定位
#層級與屬性結合
# driver.find_element_by_xpath("//form[@id='form']/span[1]/input").clear() #經過父元素進行定位
#使用邏輯運算符
# driver.find_element_by_xpath("//input[@id='kw' and @class='s_ipt']").send_keys('seleium4')

#CSS定位
# driver.find_element_by_css_selector('.s_ipt').send_keys('css定位-class') #經過class屬性定位
# driver.find_element_by_css_selector('#kw').send_keys('css定位-id') #經過id屬性定位
# driver.find_element_by_css_selector('input') #經過標籤訂位
# driver.find_element_by_css_selector('form>span>input').click() #經過父子關係定位
# driver.find_element_by_css_selector('form>span>input.s_ipt').click() #組合定位
# driver.find_element_by_css_selector('form>span>input#kw').click() #組合定位
# driver.find_element_by_css_selector('form.fm>span>input#su').click() #組合定位

from selenium.webdriver.common.by import By
#用by元素定位
# driver.find_element(By.ID,"kw").send_keys('By元素定位-id')
# driver.find_element(By.ID,"kw").clear()
# driver.find_element(By.NAME,"wd").send_keys('By元素定位-name')
# driver.find_element(By.NAME,"wd").clear()
# driver.find_element(By.CLASS_NAME,"s_ipt").send_keys('By元素定位-class-name')
# driver.find_element(By.CLASS_NAME,"s_ipt").clear()
# driver.find_element(By.TAG_NAME,"input").send_keys("By元素定位-input")
# driver.find_element(By.TAG_NAME,"input").clear()
# driver.find_element(By.LINK_TEXT,"新聞").click()
# driver.find_element(By.PARTIAL_LINK_TEXT,"新").click()
# driver.find_element(By.XPATH,"//*[@class='bg s_btn']").click()

 

3、控制瀏覽器

 import time

 

#控制瀏覽器大小(設置瀏覽器寬800,高600)
# driver.set_window_size(800,600)
#控制瀏覽器後退、前進
# driver.find_element_by_link_text('新聞').click()
# driver.back() #後退
# driver.forward() #前進
#模擬瀏覽器刷新
# driver.find_element_by_id("kw").send_keys("selenium")
# driver.find_element_by_id("su").click()
# time.sleep(2)
# driver.refresh()
# driver.quit()

 

4、簡單元素操做

 

from selenium import webdriver
import time
driver = webdriver.Ie()
# driver.get('https://login.xiu.com/')

#clear() 清除文本
#send_keys() 模擬按鍵輸入
#click() 單擊元素
#模擬走秀網登陸
# driver.find_element_by_link_text("密碼登陸").click()
# driver.find_element_by_id("J_username").clear()
# driver.find_element_by_id("J_username").send_keys("13684995613")
# driver.find_element_by_id("J_password").clear()
# driver.find_element_by_id("J_password").send_keys("jmy@123")
# driver.find_element_by_id("login_Btn").click()
# driver.quit()

#webelement接口經常使用方法

driver.get("http://www.baidu.com")

# driver.find_element_by_id("kw").send_keys("webelement接口經常使用方法")
# driver.find_element_by_id("kw").submit() #用於提交表單
# print(driver.find_element_by_id("kw").size) #得到輸入框尺寸({'height': 22, 'width': 500})
# print(driver.find_element_by_id("cp").text) #得到text值(©2017 Baidu 使用百度前必讀 意見反饋 京ICP證030173號 京公網安備11000002000001號 )
# print(driver.find_element_by_id("kw").get_attribute('type')) #得到元素的屬性(text):id/name/type或其餘任意屬性
# print(driver.find_element_by_id("kw").is_displayed()) #返回元素是否可見(True)

 

5、鼠標事件

 

#ActionChains類提供了一些鼠標操做的方法(右擊、雙擊、懸浮、鼠標拖動等)
# import time
# from selenium import webdriver
# from selenium.webdriver.common.action_chains import ActionChains
# driver = webdriver.Ie()
# driver.get("http://www.baidu.com")
#鼠標右擊操做
# right_click = driver.find_element_by_link_text("新聞") #定位到要執行的元素
# ActionChains(driver).context_click(right_click).perform() #執行右擊操做(ActionChains()將瀏覽器驅動driver做爲參數傳入;context_click()方法用於模擬鼠標右鍵操做;perform()執行全部ActionChains中存儲的行爲)

# 鼠標懸浮
# above = driver.find_element_by_link_text("設置")
# ActionChains(driver).move_to_element(above).perform()
# time.sleep(2)
# driver.quit()

#鼠標雙擊操做
# double_click = driver.find_element_by_id("su")
# ActionChains(driver).double_click(double_click).perform()
# driver.quit()

#拖放鼠標
# element = driver.find_element_by_id("xx")
# target = driver.find_element_by_id("xx")
# ActionChains(driver).drag_and_drop(element,target).perform() #在element元素上按住鼠標左鍵,而後移動到target元素上釋放

 

6、鍵盤事件

 

#Keys()類提供了鍵盤上幾乎全部的按鍵方法。
# import time
# from selenium import webdriver
# from selenium.webdriver.common.keys import Keys
# driver = webdriver.Ie()
# driver.get("http://www.baidu.com")

#輸入框輸入內容
# driver.find_element_by_id("kw").send_keys("selenium")
#刪除一個字母
# driver.find_element_by_id("kw").send_keys(Keys.BACK_SPACE)
#輸入含空格鍵
# driver.find_element_by_id("kw").send_keys(Keys.SPACE)
# driver.find_element_by_id("kw").send_keys("好孩子")
#全選輸入框內容
# driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'a')
#剪切輸入框內容
# driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'x')
#粘貼內容到輸入框
# driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'v')
#經過鍵盤代替單擊操做
# driver.find_element_by_id("su").send_keys(Keys.ENTER)
#F12鍵
# driver.find_element_by_id("kw").send_keys(Keys.F12)
# time.sleep(2)
# driver.quit()

 

7、得到驗證碼信息

 

# from selenium import webdriver
# import time
# driver = webdriver.Ie()
# driver.get("https://login.xiu.com/")
# driver.find_element_by_link_text("密碼登陸").click()
# time.sleep(2)
# driver.refresh() #運維把登陸頁限速了,所以這裏等待刷新下
# time.sleep(2)
# driver.find_element_by_id("J_username").clear()
# driver.find_element_by_id("J_username").send_keys("13684995613")
# driver.find_element_by_id("J_password").clear()
# driver.find_element_by_id("J_password").send_keys("jmy@123")
# driver.find_element_by_id("login_Btn").click()
# name = driver.find_element_by_xpath(".//*[@id='logindiv']/a[1]").text
# if name == '大熊二':
# print("登陸成功")
# else:
# print("登陸錯誤")
# driver.quit()

 

8、設置元素等待

 

# webdriver提供了兩種類型的等待:顯示等待和隱式等待
# 1.顯示等待:某個條件成立時繼續執行,不然在達到最大時長時拋棄超時異常(TimeoutException)


#2.隱式等待:經過必定的時長等待頁面上某元素加載完成。如超出了設置的時長元素還未加載,則拋出NoSuchElementException異常
# from selenium import webdriver
# from selenium.common.exceptions import NoSuchElementException
# from time import ctime

# driver = webdriver.Ie()
#設置隱式等待爲10S
# driver.implicitly_wait(10)
# driver.get("http://www.baidu.com")
# try:
# print(ctime())
# driver.find_element_by_id("kw111").send_keys("selenium")
# except NoSuchElementException as e:
# print(e)
# finally:
# print(ctime())
# driver.quit()

 

9、定位一組元素

 

# from selenium import webdriver
# driver = webdriver.Ie()
# driver.get("http://www.baidu.com")
# driver.find_elements_by_id()
# driver.find_elements_by_name()
# driver.find_elements_by_class_name()
# driver.find_elements_by_tag_name()
# driver.find_elements_by_link_text()
# driver.find_elements_by_partial_link_text()
# driver.find_elements_by_xpath()
# driver.find_elements_by_css_selector()
#若是隻想勾選一組元素中的某一個則用pop().lick():
# pop() 或pop(-1) 默認獲取一組元素中的最後一個
# pop(0) 默認獲取一組元素中的第一個
# pop(1) 默認獲取一組元素中的第二個

 

10、多表單切換

 

#webdriver只能在一個頁面上對元素識別和定位,對於frame/iframe表單內嵌頁面上的元素沒法直接定位。
這時就須要經過switch_to.frame()方法將當前定位的主題切換爲frame/iframe表單的內嵌頁面中
switch_to.frame()默承認以直接取表單的id或name。若是iframe沒有可用的id和name屬性,則能夠經過xpath先定位表單,而後再傳給switch_to.frame()

from selenium import webdriver
import time
import os

driver = webdriver.Ie()
file_path = 'file:///' + os.path.abspath('a.html') #本身寫了一個表單內嵌的HTML
driver.get(file_path)
#切換到iframe(id= "if")的表單
driver.switch_to.frame("if")
driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()
time.sleep(2)
driver.quit()

 

11、多窗口切換

 

#webdriver提供了switch_to_window()的方法,實如今不一樣的窗口之間切換
from selenium import webdriver
import time
driver = webdriver.Ie()
driver.implicitly_wait(10)
driver.get("http://www.baidu.com")

sreach_window = driver.current_window_handle
driver.find_element_by_link_text("登陸").click()
driver.find_element_by_link_text("當即註冊").click()


all_handls = driver.window_handles

for handle in all_handls:
if handle != sreach_window:
driver.switch_to_window(handle)
print('now sreach window!')
driver.find_element_by_id("TANGRAM__PSP_3__userName").send_keys("username")
driver.find_element_by_id("TANGRAM__PSP_3__phone").send_keys("13684995613")
time.sleep(2)

for handle in all_handls:
if handle == sreach_window:
driver.switch_to_window(handle)
print('now sreach window!')
driver.find_element_by_id("TANGRAM__PSP_4__closeBtn").click()
driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()
time.sleep(2)
driver.quit()

 

12、警告框處理

 

#在webdriver中處理JavaScript所生成的alert、confirm、prompt,使用switch_to_alert()方法定位到alert/confirm/prompt,而後用text/accept/dismiss/send_keys等方法進行操做
#text: 返回alert/confirm/prompt中的文字信息
#accept() 接受現有警告框
#dismiss() 解散現有警告框
#send_keys(keysToSend):發送文本至警告框
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import time

driver = webdriver.Ie()
driver.implicitly_wait(10)
driver.get("http://www.baidu.com")

link = driver.find_element_by_link_text("設置")
ActionChains(driver).move_to_element(link).perform()

driver.find_element_by_link_text("搜索設置").click()

driver.find_element_by_class_name("prefpanelgo").click()
time.sleep(2)

driver.switch_to_alert().accept()
driver.quit()

 

十3、上傳文件

 

#對於web頁面的上傳功能實現通常有如下兩種方式:
# 1.普通上傳:普通的附件上傳是將本地文件的路徑做爲一個值放在input標籤中,經過form表單將這個值提交給服務器
# 2.插件上傳:通常是基於flash、JavaScript、ajax等技術所實現的上傳功能

# 1.send_keys實現上傳

from selenium import webdriver
import os

driver = webdriver.Ie()
file_path = 'file:///' + os.path.abspath('b.html') #本身寫的一個上傳的HTML
driver.get(file_path)

driver.find_element_by_name("file").send_keys("D:\\upload_file.txt")
driver.quit()

# 2.經過Autolt實現(略)

十4、下載文件

 

from selenium import webdriver
import os
driver = webdriver.FirefoxProfile()
driver.set_preference("browser.download.folderList",2) #設置爲0下載到瀏覽器默認下載目錄,設置2能夠保存到指定目錄
driver.set_preference("browser.download.manager.showWhenStarting",False) #True爲顯示, False不顯示
driver.set_preference("browser.download.dir",os.getcwd()) #os.getcwd()用戶返回當前目錄
driver.set_preference("browser.helperApps.neverAsk.saveToDisk","application/octet-stream") #指定要下載頁面的content-type值:application/octet-stream

driver1 = webdriver.Firefox(firefox_profile=driver)
driver1.get("http://pypi.python.org/pypi/selenium")
driver1.find_element_by_partial_link_text("selenium-3.6.0.tar.gz").click()
driver1.quit()

 

十5、操做cookie

 

#webdriver操做cookie的方法(cookie數據是以字典的形式存放的):
# get_cookies(): 得到全部cookie信息
# get_cookies(name): 返回字典的key爲name的cookie信息
# add_cookie(cookie_dict): 添加cookie。「cookie_dict」指字典對象,必須有name和value值
# delete_cookie(name,optionsString):刪除cookie信息,「name」是要刪除的cookie的名稱,optionsString是該cookie的選項
# delete_all_cookies(): 刪除全部cookie信息

from selenium import webdriver
import time
driver = webdriver.Firefox()
driver.get("http://www.youdao.com")
time.sleep(3)
driver.add_cookie({"name":"key-aaaaaaa",'value':'value-aaaaaaa'})
# time.sleep(3)
for cookie in driver.get_cookies():
print("%s -> %s" % (cookie['name'],cookie['value']))

driver.quit()

 

十6、調用JavaScript

 

#調用JavaScript控制瀏覽器滾動條

from selenium import webdriver
import time
driver = webdriver.Firefox()
driver.get("http://www.baidu.com")
driver.set_window_size(600,600)

driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()
time.sleep(2)

#設置滾動條滾動的位置
js = "window.scrollTo(600,450);"
driver.execute_script(js)
time.sleep(2)
driver.quit()

 

十7、窗口截圖

 

#腳本執行過程當中出錯時候截圖保存

from selenium import webdriver
import time
driver = webdriver.Firefox()
driver.get("http://www.baidu.com")

driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()
time.sleep(3)
#截取當前窗口,並指定截圖圖片的保存位置
driver.get_screenshot_as_file("D:\\picture\\baidu_img.jpg")
driver.quit()

十8、驗證碼處理

 

# 1.去掉 驗證碼# 2.設置萬能驗證碼# 3.驗證碼識別技術# 4.記錄cookie(經過添加cookie的方式將用戶名和密碼寫入cookie,這樣的話再次訪問的時候就能夠直接登陸了)