Selenium是一個(gè)Web的自動(dòng)化測試工具,最初是為網(wǎng)站自動(dòng)化測試而開發(fā)的,類型像我們玩游戲用的按鍵精靈,可以按指定的命令自動(dòng)操作,不同是Selenium 可以直接運(yùn)行在瀏覽器上,它支持所有主流的瀏覽器(包括PhantomJS這些無界面的瀏覽器)。
PhantomJS
是一個(gè)基于Webkit的“無界面”(headless)瀏覽器,它會(huì)把網(wǎng)站加載到內(nèi)存并執(zhí)行頁面上的 JavaScript,因?yàn)椴粫?huì)展示圖形界面,所以運(yùn)行起來比完整的瀏覽器要高效。
1、如果我們把 Selenium 和 PhantomJS 結(jié)合在一起,就可以運(yùn)行一個(gè)非常強(qiáng)大的網(wǎng)絡(luò)爬蟲了,這個(gè)爬蟲可以處理 JavaScrip、Cookie、headers,以及任何我們真實(shí)用戶需要做的事情。
# 導(dǎo)入 webdriver
from selenium import webdriver
# 要想調(diào)用鍵盤按鍵操作需要引入keys包
from selenium.webdriver.common.keys import Keys
# 調(diào)用環(huán)境變量指定的PhantomJS瀏覽器創(chuàng)建瀏覽器對(duì)象
driver = webdriver.PhantomJS()
# 如果沒有在環(huán)境變量指定PhantomJS位置
# driver = webdriver.PhantomJS(executable_path="./phantomjs"))
# get方法會(huì)一直等到頁面被完全加載,然后才會(huì)繼續(xù)程序,通常測試會(huì)在這里選擇 time.sleep(2)
driver.get("http://www.baidu.com/")
# 獲取頁面名為 wrapper的id標(biāo)簽的文本內(nèi)容
data = driver.find_element_by_id("wrapper").text
# 打印數(shù)據(jù)內(nèi)容
print data
# 打印頁面標(biāo)題 "百度一下,你就知道"
print driver.title
# 生成當(dāng)前頁面快照并保存
driver.save_screenshot("baidu.png")
# id="kw"是百度搜索輸入框,輸入字符串"長城"
driver.find_element_by_id("kw").send_keys(u"長城")
# id="su"是百度搜索按鈕,click() 是模擬點(diǎn)擊
driver.find_element_by_id("su").click()
# 獲取新的頁面快照
driver.save_screenshot("長城.png")
# 打印網(wǎng)頁渲染后的源代碼
print driver.page_source
# 獲取當(dāng)前頁面Cookie
print driver.get_cookies()
# ctrl+a 全選輸入框內(nèi)容
driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'a')
# ctrl+x 剪切輸入框內(nèi)容
driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'x')
# 輸入框重新輸入內(nèi)容
driver.find_element_by_id("kw").send_keys("itcast")
# 模擬Enter回車鍵
driver.find_element_by_id("su").send_keys(Keys.RETURN)
# 清除輸入框內(nèi)容
driver.find_element_by_id("kw").clear()
# 生成新的頁面快照
driver.save_screenshot("itcast.png")
# 獲取當(dāng)前url
print driver.current_url
# 關(guān)閉當(dāng)前頁面,如果只有一個(gè)頁面,會(huì)關(guān)閉瀏覽器
# driver.close()
# 關(guān)閉瀏覽器
driver.quit()
2、鼠標(biāo)動(dòng)作鏈
#導(dǎo)入 ActionChains 類
from selenium.webdriver import ActionChains
# 鼠標(biāo)移動(dòng)到 ac 位置
ac = driver.find_element_by_xpath('element')
ActionChains(driver).move_to_element(ac).perform()
# 在 ac 位置單擊
ac = driver.find_element_by_xpath("elementA")
ActionChains(driver).move_to_element(ac).click(ac).perform()
# 在 ac 位置雙擊
ac = driver.find_element_by_xpath("elementB")
ActionChains(driver).move_to_element(ac).double_click(ac).perform()
# 在 ac 位置右擊
ac = driver.find_element_by_xpath("elementC")
ActionChains(driver).move_to_element(ac).context_click(ac).perform()
# 在 ac 位置左鍵單擊hold住
ac = driver.find_element_by_xpath('elementF')
ActionChains(driver).move_to_element(ac).click_and_hold(ac).perform()
# 將 ac1 拖拽到 ac2 位置
ac1 = driver.find_element_by_xpath('elementD')
ac2 = driver.find_element_by_xpath('elementE')
ActionChains(driver).drag_and_drop(ac1, ac2).perform()
Selenium專門提供了Select類來處理下拉框。 其實(shí) WebDriver 中提供了一個(gè)叫 Select 的方法,可以幫助我們完成這些事情:
# 導(dǎo)入 Select 類
from selenium.webdriver.support.ui import Select
# 找到 name 的選項(xiàng)卡
select = Select(driver.find_element_by_name('status'))
select.select_by_index(1)
select.select_by_value("0")
select.select_by_visible_text(u"未審核")
全部取消選擇怎么辦呢?很簡單:
select.deselect_all()
3、頁面切換
一個(gè)瀏覽器肯定會(huì)有很多窗口,所以我們肯定要有方法來實(shí)現(xiàn)窗口的切換。切換窗口的方法如下:
driver.switch_to.window("this is window name")
使用 window_handles 方法來獲取每個(gè)窗口的操作對(duì)象。例如:
for handle in driver.window_handles:
driver.switch_to_window(handle)
4、頁面等待
顯式等待
from selenium import webdriver
from selenium.webdriver.common.by import By
# WebDriverWait 庫,負(fù)責(zé)循環(huán)等待
from selenium.webdriver.support.ui import WebDriverWait
# expected_conditions 類,負(fù)責(zé)條件出發(fā)
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
driver.get("http://www.xxxxx.com/loading")
try:
# 頁面一直循環(huán),直到 id="myDynamicElement" 出現(xiàn)
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "myDynamicElement"))
)
finally:
driver.quit()
隱式等待
隱式等待比較簡單,就是簡單地設(shè)置一個(gè)等待時(shí)間,單位為秒。
from selenium import webdriver
driver = webdriver.Chrome()
driver.implicitly_wait(10) # seconds
driver.get("http://www.xxxxx.com/loading")
myDynamicElement = driver.find_element_by_id("myDynamicElement")
當(dāng)然如果不設(shè)置,默認(rèn)等待時(shí)間為0。