天天看點

玩轉Selenium——Web頁面自動化實戰

運維人員煩惱的開始

你曾經是否有這樣的境遇:日常運維的一個WEB平台,每天都要進行一些繁瑣的操作,需要你用滑鼠鍵盤不停的去點點點,有時候這些操作是高度重複的,或者是零零碎碎的分散時間需要你去操作。就拿監控工具zabbix的維護期來說(zabbix是再常見不過的監控工具了),遇到公司各大平台變更集中的時間段,每個平台負責人都會向你提出維護期申請,最令人煩惱的是,不同的申請人提出的時間不同、平台不同。于是你從早到晚的加了上百個維護期,怕自己加錯了還把每個維護期檢查了一遍,手點的都抽筋了,腦子也很混沌了,擡頭一看表晚上七點,一天就加了點維護期,上司又要批評自己了。這時候有人會說:”用zabbix-API添加維護期啊,寫寫python不就可以自動加了嗎!”奈何自己技術糙,又不想看全是文英并且傳參很麻煩的API文檔,甚至某些場景你都沒有API的詳細說明!!那怎麼辦呢?使用Selenium吧!

首先看一下Selenium的效果:

玩轉Selenium——Web頁面自動化實戰

引用官網的一句話:"Selenium測試直接運作在浏覽器中,就像真正的使用者在操作一樣"。是啊,如果用selenium幫你幹這些活,那你可以去騰出更多的時間去學習與工作。其實上面的過程放在代碼裡,主要就是分為三步走:

首先需要打開一個你想操作的網頁,然後再標明該網頁上的HTML元素,再對該元素進行一些列操作,做好這三步,就可以做出上面動圖的效果!

支援的開發環境

語言:C、java、ruby、python、JS或者是C#

平台:linux、windows、MAC

浏覽器:ie、Firefox、Safari、Opera、Chrome

是以,拿你常用的語言,常用的浏覽器去開發調試,沒有太大的限制條件(本文将用python +Chrome進行示範)。

First-快速上手

  1. 通過pip install selenium安裝。
  2. 下載下傳Chrome對應版本的WebDriver( 點選下方閱讀原文即可跳轉)
  3. 編寫代碼:
from selenium import webdriver              import time                      if __name__ == '__main__':                 chrome_driver = 'C:\\xxx\\Google\\Chrome\\Application\\chromedriver.exe'  # chromedriver的檔案位置                 driver = webdriver.Chrome(executable_path=chrome_driver)                 driver.get('https://www.baidu.com')                 driver.find_element_by_id('kw').send_keys('Hello,')                 time.sleep(1) # 為了友善展示加了點延遲                 driver.find_element_by_id('kw').send_keys('光大科技')              driver.find_element_by_id("su").click()           
玩轉Selenium——Web頁面自動化實戰

通過上述簡單的插件安裝與幾行python代碼,就實作了自動打開“百度”,輸入”Hello,光大科技“,并點選搜尋的功能,是不是簡潔至極!值得一提的是,這是Selenium的有操作界面啟動模式,即可以看到它執行過程中的操作頁面,點選了哪裡都可以看到。但是我們大部分Linux伺服器可是沒有操作界面的呀!是的,還有一種模式叫Headless啟動模式,可以在不打開浏覽器的前提下,使用所有Chrome支援的特性運作你的程式。相比于現代浏覽器,Headless Chrome更加友善測試web應用,獲得網站的截圖,做爬蟲抓取資訊等。相比于較早的PhantomJS、SlimerJS等,Headless Chrome則更加貼近浏覽器環境。

Second-元素定位

看完上面的快速開始,可能你還不知道,為什麼代碼可以執行輸入、搜尋這些功能。其實這都歸功于元素的定位,并對定位後的元素進行一些操作執行,就例如上面的:

driver.find_element_by_id('kw')driver.find_element_by_id("su")      

選擇id為"kw"與"su"的元素,百度搜尋首頁HTML内容如下:

玩轉Selenium——Web頁面自動化實戰

其實就是通過標明HTML上的元素ID “kw”(即百度搜尋輸入框input),然後再輸入了“光大科技”這個String。熟悉前端的開發人員應該對HTML的元素并不陌生,老牌勁旅JQuery中就有常用的元素選擇器,如ID選擇器$("#id"),類選擇器$(".className")等等,find_element_by_id('kw')就是通過選擇ID元素來進行元素定位的。這時前端開發的同學又要說了:“JQuery我早就不用了!現在都用火爆的三大架構,網頁哪有那麼多元素綁定ID?”。是的,但是不要慌,webdriver提供了很多元素定位方法,不隻是綁定ID:

id定位:find_element_by_id()

name定位:find_element_by_name()

class定位:find_element_by_class_name()

link定位:find_element_by_link_text()

partial link定位:find_element_by_partial_link_text()

tag定位:find_element_by_tag_name()

xpath定位:find_element_by_xpath()

css定位:find_element_by_css_selector()

id、name、class這些就不用多說了,直接標明就可以用。link定位,此種方法是專門用來定位文本連結的,比如百度首頁右上角有“新聞”,“hao123”,“地圖”等連結。如果懂HTML知識,我們就知道HTML是通過tag來定義功能的,比如input是輸入,table是表格,等等。每個元素其實就是一個tag,一個tag往往用來定義一類功能,我們檢視百度首頁的html代碼,可以看到有很多div、input、a等tag,是以很難通過tag去區分不同的元素,這個不常用。其中,個人認為功能最強大的是xpath定位,find_element_by_xpath(),它是基于HTML文檔目錄結構進行元素定位的(html的DOM樹),理論上可以通過路徑、索引、屬性值、軸定位、文本test定位到幾乎全部的元素,聽起來就很強,但是用法也相對其他方法複雜一點點,且要具備HTML DOM的知識,舉幾個常用的例子如下:

多元素屬性值定位(相對路徑):xpath= "//标簽名[@type='XX' and @name='XX']" (type、name均為屬性名)

絕對路徑定位:xpath = " /html/body/div/标簽名[@屬性="屬性值"]"(定位到body下的某個div下的元素,如果div很多,可以通過div[@屬性值="xx"]來具體到某個div),但是絕對路徑方法維護成本太高,一般不用

test()文本定位:xpath = "//标簽名[text()='上一步']"

索引定位:xpath = "//标簽名[2]"如 //input[2]定位到body中第三個input标簽

軸定位:用::表示,選擇目前節點的父節點(parent)、子節點(child)、祖先節點(ancestor)、子孫節點(descendant)、後節點(following)前節點(preceding)、後兄弟節點(following-sibling)、前兄弟節點(preceding-sibling)xpath="//标簽/關系關鍵字::标簽",如//div[1]/child::img,就是尋找div[1]的子節點img

Xpath方法還是需要多用,多見見複雜的html dom結構,在實戰中提升使用技巧,對于定位而言它幾乎是萬能的,有興趣的同學可以仔細研究研究~

html dom樹結構參考

- 左右滑動檢視更多 -

玩轉Selenium——Web頁面自動化實戰
玩轉Selenium——Web頁面自動化實戰

圖檔來源于網絡

third-操作方法

通過上面的元素定位,現在同學們已經可以随心所欲的定位自己想要的元素了,那接下來就應該對所取元素進行一些快樂的操作!就如開始的demo中:

driver.find_element_by_id('kw').send_keys('Hello,')driver.find_element_by_id("su").click()      

上面.send_keys().click()就是響應的元素操作,對你選中的元素進行傳值、點選等等。

總結了一下相關操作方法,以百度搜尋首頁為例,進行操作:

driver.find_element_by_name('wd').send_keys(‘PythonSelenium’),#在百度文本搜尋框内輸入内容Python Seleniumdriver.find_element_by_name('wd').clear(),#清空文本搜尋框的所有内容driver.find_element_by_id('su').click(),#點選搜尋按鈕driver.find_element_by_id('su').submit(),#送出搜尋按鈕,這裡效果同點選搜尋按鈕driver.find_element_by_id('kw').size,#擷取搜尋框的大小driver.find_element_by_id('jgwab').text,#擷取控件id為’jgwab’所顯示的内容driver.find_element_by_id('su').get_attribute('type'),#擷取控件id為’su’的屬性,例如button,radio等driver.find_element_by_name('wd').is_displayed(),#判斷搜尋文本框目前是否被顯示      

當然也不隻有簡單的點點點,隻要是日常操作滑鼠鍵盤能實作的(模拟鍵鼠操作),Selenium都可以實作,舉例如下:

driver.find_element_by_id('kw').send_keys(Keys.BACK_SPACE)#Backspace鍵driver.find_element_by_id('kw').send_keys(Keys.SPACE)#Space鍵driver.find_element_by_id('kw').send_keys(Keys.DELETE)#Delete鍵driver.find_element_by_id('kw').send_keys(Keys.CONTROL,'a')# CTRL + AActionChains(driver).context_click(driver.find_element_by_id('kw')).perform()#在搜尋文本框利用context_click()進行滑鼠右擊,perform()是執行方法的語句ActionChains(driver).double_click(driver.find_element_by_id('kw')).perform()#在搜尋文本框利用double_click()進行輕按兩下, perform()是執行方法的語句ActionChains(driver).drag_and_drop(driver.find_element_by_id('kw'),driver.find_element_by_id('su')).perform()#利用drag_and_drop(source,target)從搜尋文本框移動到點選按鈕,perform()是執行方法的語句      

這些都是一些常用且實用的操作,相信你一定會用到!想了解更高階玩法的小夥伴們可以自行學習~

The end-打包、使用

當你按照三步走寫完你的python代碼,并且運作正常,就可以執行打包.exe操作了。打包成.exe你的程式将可以在任何一台windos-pc上運作,可以發給你工作上的小夥伴,且不需要它本地安裝任何依賴。(當然如果不嫌麻煩,在要執行的機器上安裝好所有依賴,也可以用xxxx.py直接執行)安裝打包工具pyinstaller:

玩轉Selenium——Web頁面自動化實戰

執行打包指令:pyinstaller -F xxx.py(xxx.py,打包的檔案),生成的exe在/項目位址/dist目錄下。然後,輕按兩下,運作!

Selenium 相關其他玩法

Selenium玩爬蟲

既然能標明元素并操作元素,那一定可以做爬蟲吧!沒錯,它确實具備很多玩爬蟲的優點:對比于requests玩爬蟲來講,Selenium能擷取js動态給出的源碼,且做到模拟真實登入減少了反爬的限制。但是缺點很明顯,獲得多出來的前端渲染功能是要付出代價的,requests直接不啟動浏覽器、不渲染動态頁面,想要機關時間内爬取大量資訊,性能會差很多!有時候兩者結合面對反爬應該更好用一些~

Selenium IDE

它是一款依賴于Firefox浏覽器的插件(xpi),可以實作腳本的錄制、回放以及編輯腳本功能,元素定位等,可以利用 selenium IDE将錄制的腳本生成相應的帶單元測試架構的自動化測試腳本。如果隻用于web自動化測試,這是一個很便捷的工具,它的頁面如下。

玩轉Selenium——Web頁面自動化實戰

調用JS語言

Selenium方法execute_script(script, *args),參數可以填寫任何JavaScript語言,例如我們前端常用的alert()。浏覽器滾動條的拖動,不能依靠WebDriver提供的API來實作,是以可以調用js中的window.scrollTo(xx,xx)來設定滾動條的位置。