Selenium 與 PhantomJS

selenium和phantomjs概述

案例操作:模擬登陸csdn

1. selenium和phantomJS是什么東西?

selenium是一套web網(wǎng)站自動化測試工具,主要通過命令行的操作完成常規(guī)可視化界面下的用戶各種操作行為,因為其簡單易學(xué)成本低,并且執(zhí)行測試效率較高而在web自動化測試方面比較突出,該庫可以直接運行操作各種主流瀏覽器,輔助瀏覽器自動完成表單互動、鼠標(biāo)點擊、鼠標(biāo)拖拽、窗口切換等等各種用戶行為,是一套非常好用且強大的測試庫,但是selenium沒有內(nèi)置的瀏覽器模塊,不能獨立運行,必須要和第三方瀏覽器配合使用才可以完成自動化測試操作。在實際操作的過程中,經(jīng)常使用selenium和各大主流瀏覽器共同操作,如谷歌、火狐、IE等等,但是在selenium自動化測試發(fā)展過程中,有一個特殊的瀏覽器經(jīng)常用于和它配合使用,就是比較出名的無界面瀏覽器phantomJS。

2. 爬蟲、selenium、phantomJS這時候問題就來了,爬蟲中,為什么要涉及到selenium測試工具和無界面瀏覽器這樣的東東呢?

故事背景:那是很久的以前,人們生活在一個非常平和的年代

老李住在人民小區(qū)的一所豪宅中,人人互愛互助,路不拾遺夜不閉戶已經(jīng)成了傳統(tǒng)

這天,從遙遠(yuǎn)的他鄉(xiāng)來了一個人~老王(爬蟲),禁不住五臟廟的鬧騰,終于決定要找點吃的了,他一路獨行直接進來了老李家,把老李留給媳婦的無骨燉雞湯給吃了個精光,然后施施然瀟灑的離去了

[爬蟲老王,根據(jù)自己需要的數(shù)據(jù)對于網(wǎng)站服務(wù)器老李進行了數(shù)據(jù)采集,服務(wù)器沒有任何防范,數(shù)據(jù)直接被獲取到了!老李終于回家了,發(fā)現(xiàn)有人動了他的雞湯....于是,晚上老李家傳來了老李的慘叫聲.>

老李吸取教訓(xùn),應(yīng)該是有小區(qū)之外的人進了小區(qū),于是跟守門大媽說了一句,以后進門的人一定要問問有木有門卡(備注:門卡是小區(qū)住戶才有的一種身份卡片),有卡才讓進小區(qū),否則不允許進入

[服務(wù)器老李由于數(shù)據(jù)無端泄露導(dǎo)致出現(xiàn)了安全問題,于是進行了簡單的升級防范,針對所有進行訪問的用戶驗證其User-agent,如果User-agent不合適則禁止訪問]

老王這天又餓的不行了,但是進小區(qū)時發(fā)現(xiàn)大媽竟然要查牌,好吧,老王找到小區(qū)的某個人,請它吃了頓飯,順便看了看門卡長的什么樣子,然后自己偷偷去做了一張一模一樣的卡片,然后 老王又進去了老李家,半夜~小區(qū)又傳來了老李的慘叫

[爬蟲老王通過抓包工具進行了服務(wù)器請求的抓包,分析了請求中的各項參數(shù),在請求頭中添加了瀏覽器的User-agent的值,再次訪問服務(wù)器,順利拿到了需要采集的數(shù)據(jù)]

老李憤慨于老王的行為,再次跟門口大媽說了說,家里的東西又被人動了,大媽回憶了一下這幾天的情況,發(fā)現(xiàn)老王頻繁的進入小區(qū),于是大媽針對每天頻繁進入小區(qū)的人單獨進行了登記,注意防范,一旦出現(xiàn)就堅決不允許這樣的人再進入小區(qū)

[服務(wù)器老李針對再次數(shù)據(jù)泄露,認(rèn)識到了可能有非法用戶多次采集數(shù)據(jù)造成的,于是針對限定時間頻繁訪問數(shù)據(jù)的操作進行了屏蔽,如果出現(xiàn)1分鐘內(nèi)訪問次數(shù)超過30次的直接屏蔽ip地址]

老王這天來到小區(qū)門口,發(fā)現(xiàn)和他一樣的老孫餓的皮包骨頭,很詫異的問老孫什么情況,老孫據(jù)實說了實際情況,老孫已經(jīng)進了大媽的黑名單,再也不能進小區(qū)覓食了!老王發(fā)現(xiàn)了這個問題之后,于是~每天只進入一次小區(qū),還跟大媽很熱情的打招呼呢.....老李是徹底的憤怒了,家里的吃的雖然沒有像之前丟的那么頻繁,但是終歸還是丟了特別重要的部分,半夜時分,老李的慘叫是那么的慘絕人寰

[爬蟲老王限制了爬蟲訪問服務(wù)器的時間,根據(jù)正常用戶的發(fā)送請求的時間,限制了不同爬取請求之間的休眠時間,盡管采集數(shù)據(jù)較慢,但是同樣得到了數(shù)據(jù)]

老李這次學(xué)乖了,出門的時候給家里上鎖了,在也不愁數(shù)據(jù)數(shù)據(jù)再次丟失的問題了[服務(wù)器老李在請求參數(shù)中,添加了一個加密字段,如果參數(shù)中包含了正確的加密字段,就允許訪問數(shù)據(jù),如果參數(shù)中沒有標(biāo)注則拒絕訪問]

老王已經(jīng)餓了太多天了
老王找到了傳說中的某個大師,跟他學(xué)了曠古絕技,于是在某個艷陽高照的晴天,再次進了老李家....這天半夜,老李默默的坐了一個晚上

[爬蟲針對加密數(shù)據(jù)進行了分析追蹤,得到了加密 的具體流程,于是進行了加密字段的重現(xiàn),將加密數(shù)據(jù)通過請求傳遞給了服務(wù)器,順利獲取到了數(shù)據(jù)]

老李根據(jù)自己的需要,換了指紋密碼鎖[服務(wù)器針對數(shù)據(jù)安全問題,進行了再次升級,對數(shù)據(jù)進行了混淆編碼的同時,通過混淆編碼進行了多重加密操作,同時進行了多個字段的數(shù)字指紋簽名操作,如果請求中不包含這些數(shù)據(jù)的情況下,拒絕提供數(shù)據(jù)]

老王看著緊鎖的大門,想了很久,這天老李家來了客人,好酒好菜兩人暢談甚久,夜幕時分,老王施施然從老李家走了出來,身旁就是老李相送[客戶端老王看到服務(wù)器老李已經(jīng)做了非常復(fù)雜的反爬蟲操作,于是權(quán)衡之后不再做反扒操作,直接讓自己變成了正式用戶發(fā)送請求,同樣獲取到了數(shù)據(jù)]

而這里涉及到的正式用戶的請求,就是直接通過瀏覽器發(fā)送請求訪問服務(wù)器,用到的瀏覽器就是phantomJS無界面瀏覽器,通過selenium測試工具發(fā)送請求操作訪問過程獲取數(shù)據(jù)

準(zhǔn)備工作:selenium和PhantomJS
phantomjs:一個獨立的無界面瀏覽器,并不是python模塊,所以需要單獨下載安裝;

phantomjs官方網(wǎng)站:http://phantomjs.org/

selenium:獨立的第三方模塊,通過pip install selenium進行安裝

PhantomJS

PhantomJS是一個基于Webkit的'無界面'瀏覽器
phantomJS 官網(wǎng)參考文檔:http://phantomjs.org/documentation
官網(wǎng)下載安裝: http://phantomjs.org/download.html
1、解壓放到:C:\phantomjs-2.1.1-windows
2、需要設(shè)置環(huán)境變量,Path中添加
C:\phantomjs-2.1.1-windows\bin
3、在控制臺中輸入phantomjs -v,若輸出了版本號,則證明安裝成功

Chrome dirver的安裝

1、打開如下頁面:
https://sites.google.com/a/chromium.org/chromedriver/downloads
對照下載說明,找到對應(yīng)的ChromeDriver版本
2、打開如下頁面:
http://chromedriver.storage.googleapis.com/index.html
找到對應(yīng)的版本,下載對應(yīng)文件

案例

# 導(dǎo)入 webdriver
from selenium import webdriver
# 要想調(diào)用鍵盤按鍵操作需要引入 keys 包
from selenium.webdriver.common.keys import Keys
# 調(diào)用環(huán)境變量指定的 PhantomJS 瀏覽器創(chuàng)建瀏覽器對象
driver = webdriver.PhantomJS()
# get 方法會一直等到頁面被完全加載,然后才會繼續(xù)程序,通常測試會在這里選擇
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("奇酷信息")
# id="su"是百度搜索按鈕,click() 是模擬點擊
driver.find_element_by_id("su").click()
# 獲取新的頁面快照
driver.save_screenshot("奇酷信息.png")
# 打印網(wǎng)頁渲染后的源代碼
print(driver.page_source)
print('============')
# 獲取當(dāng)前頁面 Cookie
print(driver.get_cookies())
# 清除輸入框內(nèi)容
driver.find_element_by_id("kw").clear()
print('============')
# 獲取當(dāng)前 url
print(driver.current_url)
# 關(guān)閉當(dāng)前頁面,如果只有一個頁面,會關(guān)閉瀏覽器
driver.close()
# 關(guān)閉瀏覽器
driver.quit()

定位元素

單個元素查找
find_element_by_name
find_element_by_id
find_element_by_xpath
find_element_by_link_text
find_element_by_partial_link_text
find_element_by_tag_name
find_element_by_class_name
find_element_by_css_selector
多個元素查找
find_elements_by_name
find_elements_by_id
find_elements_by_xpath
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

ActionChains

在頁面上模擬一些鼠標(biāo)操作,比如雙擊、右擊、拖拽甚至按住不動等,可以通過導(dǎo)入ActionChains類實現(xiàn)
案例:

menu = driver.find_element_by_css_selector(".nav")
hidden_submenu = driver.find_element_by_css_selector(".nav #submenu1")
ActionChains(driver).move_to_element(menu).click(hidden_submenu).perform()
ActionChains方法列表
方法列表.jpg

selenium核心API

  • selenium.webdriver
  • selenium核心驅(qū)動模塊,主要包含了web服務(wù)相關(guān)的核心操作,可以調(diào)用指定的服務(wù)器
driver = selenium.webdriver.PhantomJS() 
driver = selenium.webdriver.Chrome()
  • 瀏覽器填寫url地址訪問文章:
    driver.get("http://www.baidu.com")
  • 獲取標(biāo)簽對象 find_element_by_id()
    根據(jù)標(biāo)簽編號查詢標(biāo)簽對driver.find_by_element_by_id("box")
  • 同下:
from selenium.webdriver.common.by import By *
driver.find_element(by=By.ID, value='box') 
find_elements_by_name() 
  • 根據(jù)標(biāo)簽的name屬性只查詢標(biāo)簽對象
    driver.find_elements_by_name("real_name")

  • 同下:

from selenium.webdriver.common.by import By *
driver.find_elemnets(by=By.NAME, value='real_name') 
find_elemnets_by_xpath()
  • 根據(jù)xpath語法查詢指定的標(biāo)簽
    driver.find_elements_by_xpath('//input[id="kw"]')
  • 同下:
from selenium.webdriver.common.by import By *
driver.find_elements(by=By.XPATH, value='//input[@id="kw"]')
find_elements_by_link_text() 
  • 根據(jù)超鏈接標(biāo)簽鏈接文本查詢標(biāo)簽
    driver.find_elements_by_link_text('damu')
  • 同下:
from selenium.webdriver.common.by import By *
driver.find_elements(by=By.LINK_TEXT, value='damu') 
find_elemetns_by_partial_link_text() 
  • 根據(jù)超鏈接標(biāo)簽鏈接文本 擴展 查詢標(biāo)簽
    driver.find_elements_by_partial_link_text('damu')
  • 同下:
from selenium.webdriver.common.by import By *
driver.find_elements(by=By.PARTIAL_LINK_TEXT, value='damu') 
find_elements_by_tag_name() 
  • 根據(jù)標(biāo)簽名稱查詢標(biāo)簽
    driver.find_elements_by_tag_text('damu')
  • 同下:
from selenium.webdriver.common.by import By *
driver.find_elements(by=By.TAG_NAME, value='damu') 
find_elements_by_class_name() 
  • 根據(jù)標(biāo)簽的class名稱查詢標(biāo)簽
    driver.find_elements_by_class_name("")
    同下:
from selenium.webdriver.common.by import By *
driver.find_elements(by=By.CLASS_NAME)
find_elements_by_css_selector() 
  • 根據(jù)標(biāo)簽的樣式名稱查詢得到標(biāo)簽
    driver.find_elements_by_css_selector("#box > div")
  • 同下:
from selenium.webdriver.common.by import By *
driver.find_elements(by=By.CSS_SELECT, value='#box')
  • selenium.webdirver.common.keys.Keys
  • selenium用于操作用戶鍵盤的核心模塊
  • 表單處理:輸入框填寫數(shù)據(jù)
  • 選擇輸入框:kw = driver.find_element_by_id("kw")
  • 輸入數(shù)據(jù):kw.send_keys(u"關(guān)鍵字")
  • 表單處理:下拉列表框選擇數(shù)據(jù)
from selenium.webdriver.support.ui import Select *
選擇下拉框:sl = Select(driver.find_element_by_id("city"))        
輸入選擇的值: sl.select_by_index(1) 
根據(jù)值的索引賦值:sl.select_by_value("zhengzhou") 
根據(jù)具體下拉框的value賦值:sl.select_by_visible_text("鄭州")
根據(jù)下拉框顯示的值賦值:sl.deselect_all() 

全部取消 * 鍵盤按鍵:功能鍵+字母按鍵

from selenium.webdriver.common.keys import Keys
driver.find_element_by_id("kw").send_keys(Keys.CONTROL, "a")
# ctrl+a全選 * ALT:alt按鍵 * NUMBER1:數(shù)字鍵1 * LFET:←左方向鍵 * F1:功能鍵F1 
* 更多more~
selenium.webdriver.ActionChains 該模塊包含了和鼠標(biāo)操作相關(guān)的行為
模擬鼠標(biāo)單擊  driver.find_element_by_id("su").click() 
from selenium.webdriver import ActionChains # 引入鼠標(biāo)模塊 
su = driver.find_element_by_id("su") # 獲取標(biāo)簽對象 
ActionChains(driver).move_to_element(su).perform()# 鼠標(biāo)移動到對象上
ActionChains(driver).move_to_element(su).click(su).perform() # 鼠標(biāo)單擊
ActionChains(driver).move_to_element(su).double_click(su).perform()# 鼠標(biāo)雙擊 
ActionChains(driver).move_to_element(su).context_click(su).perform()# 鼠標(biāo)右鍵單擊
ActionChains(driver).move_to_element(su).click_to_hold(su).perform()# 鼠標(biāo)單擊并按住 
pos1 = driver.find_element_by_element("pos1") 
pos2 = driver.find_element_by_element("pos2")
ActionChains(driver).drag_and_drop(pos1, pos2).perform() # 鼠標(biāo)將pos1脫拽到pos2的位置
* 頁面窗口操作 * 
driver.switch_to.window("window name")# 窗口誒切換 
driver.forward()# 導(dǎo)航前進 
driver.back()# 導(dǎo)航后退
* cookie操作 *
 driver.get_cookies() 獲取當(dāng)前正在訪問url地址的所有cookies數(shù)據(jù) 
* driver.delete_cookie(key) 根據(jù)key值刪除對應(yīng)的cookie數(shù)據(jù) 
* driver.delete_all_cookies() 清空cookie* 網(wǎng)頁延時:針對網(wǎng)頁中通過Ajax異步加載Json數(shù)據(jù)的情況,不同的網(wǎng)速下返回Json數(shù)據(jù)并渲染頁面會有延遲,網(wǎng)頁中并不一定能正常獲取數(shù)據(jù),需要延時操作 * 顯式等待 
# coding:utf-8 
from selenium import webdriver 
from selenium.webdriver.common.by import By 
from selenium.webdriver.support.ui import WebDriverWait 
from selenium.webdirver.support import except_conditions as EC 
driver = webdriver.PhantomJS()
driver.get("http://www.baidu.com") 
try: 
  # 獲取標(biāo)簽:間隔10S獲取標(biāo)簽~一直等待到標(biāo)簽獲取成功 
  element = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "box")) )
finally: 
  driver.quit() 

這里的等待條件,就是except_conditions調(diào)用時執(zhí)行的函數(shù),內(nèi)置如下條件可以直接調(diào)用

 title_is title_contains presence_of_element_located visibility_of_element_located visibility_of presence_of_all_elements_located text_to_be_present_in_element text_to_be_present_in_element_value frame_to_be_available_and_switch_to_it invisibility_of_element_located element_to_be_clickable – it is Displayed and Enabled. staleness_of element_to_be_selected element_located_to_be_selected element_selection_state_to_be element_located_selection_state_to_be alert_is_present 
  • 隱時等待:設(shè)置一個等待時間即可
# coding:utf-8 
from selenium import webdriver 
driver = webdriver.PhantomJS() driver.implicitly_wait(10)
driver.get("http://www.baidu.com")
driver.find_element_by_id("su") 

以上,是selenium核心的幾個API操作方式

案例:CSDN登錄真實用戶登錄CSDN場景:

  • 用戶打開瀏覽器,訪問并打開csdn登錄網(wǎng)頁
  • 填寫賬號、密碼,點擊登錄
  • 進入CSDN主頁selenium配合phantomjs完成登錄操作,并保存數(shù)據(jù)到文件中
# coding:utf-8
from selenium import webdriver
driver = webdriver.PhantomJS("./phantomjs-2.1.1/bin/phantomjs")
# 訪問登錄頁面
driver.get("https://passport.csdn.net/account/login?ref=toolbar")
# 保存登錄頁面截圖
driver.save_screenshot("csdn1.png")
# 獲取登錄 用戶輸入框、密碼輸入框
u_name = driver.find_element_by_id("username").send_keys("damumoye")
p_word = driver.find_element_by_id("password").send_keys("********")
# 模擬點擊登錄
login_btn = driver.find_element_by_css_selector("#fm1 .logging")login_btn.click()
# 保存登錄后的截圖
driver.save_screenshot("csdn2.png")
# 保存數(shù)據(jù)
with open("csdn.html", "w") as f: 
  f.write(driver.page_source.encode("utf-8"))
# 退出瀏覽器
driver.quit()
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容