selenium和phantomJS

# selenium和phantomJS

——編輯:大牧莫邪

### 目錄清單

- [x].selenium和phantomjs概述

- [x].selenium常用API

- [x].案例操作:模擬登陸csdn

### 課程內(nèi)容

#### 1. selenium和phantomJS是什么東西

selenium是一套web網(wǎng)站自動化測試工具,主要通過命令行的操作完成常規(guī)可視化界面下的用戶各種操作行為鞠呈,因為其簡單易學(xué)成本低赤套,并且執(zhí)行測試效率較高而在web自動化測試方面比較突出入录,該庫可以直接運(yùn)行操作各種主流瀏覽器,輔助瀏覽器自動完成表單互動苇羡、鼠標(biāo)點擊感局、鼠標(biāo)拖拽扫茅、窗口切換等等各種用戶行為于微,是一套非常好用且強(qiáng)大的測試庫逗嫡,但是selenium沒有內(nèi)置的瀏覽器模塊,不能獨(dú)立運(yùn)行株依,必須要和第三方瀏覽器配合使用才可以完成自動化測試操作驱证。

在實際操作的過程中,經(jīng)常使用selenium和各大主流瀏覽器共同操作恋腕,如谷歌雷滚、火狐、IE等等吗坚,但是在selenium自動化測試發(fā)展過程中,有一個特殊的瀏覽器經(jīng)常用于和它配合使用呆万,就是比較出名的無界面瀏覽器phantomJS商源。

#### 2. 爬蟲、selenium谋减、phantomJS

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

說來話長了

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

>

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

> -------------

> 這天总寻,從遙遠(yuǎn)的他鄉(xiāng)來了一個人

~老王(爬蟲),禁不住五臟廟的鬧騰梢为,終于決定要找點吃的了渐行,他一路獨(dú)行直接進(jìn)來了老李家,把老李留給媳婦的無骨燉雞湯給吃了個精光铸董,然后施施然瀟灑的離去了..

> [ ** 爬蟲老王祟印,根據(jù)自己需要的數(shù)據(jù)對于網(wǎng)站服務(wù)器老李進(jìn)行了數(shù)據(jù)采集,服務(wù)器沒有任何防范粟害,數(shù)據(jù)直接被獲取到了蕴忆! **]

> -------------

> 老李終于回家了,發(fā)現(xiàn)有人動了他的雞湯....于是悲幅,晚上老李家傳來了老李的慘叫聲.

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

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

> -------------

> 老王這天又餓的不行了,但是進(jìn)小區(qū)時發(fā)現(xiàn)大媽竟然要查牌拔疚,好吧肥隆,~老王找到小區(qū)的某個人,請它吃了頓飯稚失,順便看了看門卡長的什么樣子栋艳,然后自己偷偷去做了一張一模一樣的卡片,然后

~ 老王又進(jìn)去了老李家句各,半夜

~小區(qū)又傳來了老李的慘叫

~~~

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

> -------------

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

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

>

> <> -------------

> 老王這天來到小區(qū)門口势似,發(fā)現(xiàn)和他一樣的老孫餓的皮包骨頭拌夏,很詫異的問老孫什么情況,老孫據(jù)實說了實際情況履因,老孫已經(jīng)進(jìn)了大媽的黑名單障簿,再也不能進(jìn)小區(qū)覓食了!老王發(fā)現(xiàn)了這個問題之后栅迄,于是

~每天只進(jì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é)了曠古絕技茶宵,于是在某個艷陽高照的晴天危纫,再次進(jìn)了老李家....這天半夜,老李默默的坐了一個晚上[ ** 爬蟲針對加密數(shù)據(jù)進(jìn)行了分析追蹤乌庶,得到了加密

的具體流程种蝶,于是進(jìn)行了加密字段的重現(xiàn),將加密數(shù)據(jù)通過請求傳遞給了服務(wù)器瞒大,順利獲取到了數(shù)據(jù) **]

>

> <> -------------

> 老李根據(jù)自己的需要蛤吓,換了指紋密碼鎖[ ** 服務(wù)器針對數(shù)據(jù)安全問題,進(jìn)行了再次升級糠赦,對數(shù)據(jù)進(jìn)行了混淆編碼的同時,通過混淆編碼進(jìn)行了多重加密操作锅棕,同時進(jìn)行了多個字段的數(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:一個獨(dú)立的無界面瀏覽器,并不是python模塊,所以需要單獨(dú)下載安裝稻薇;phantomjs官方網(wǎng)站:http: // phantomjs.org / **

** selenium:獨(dú)立的第三方模塊嫂冻,通過

`pip

install

selenium

`進(jìn)行安裝 **

#### 3. selenium核心API

*selenium.webdriver

*selenium核心驅(qū)動模塊,主要包含了web服務(wù)相關(guān)的核心操作塞椎,可以調(diào)用指定的服務(wù)器

*如:driver = selenium.webdriver.PhantomJS()

*如:driver = selenium.webdriver.Chrome()

*接續(xù):瀏覽器填寫url地址訪問文章:

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

*接續(xù):獲取標(biāo)簽對象

*find_element_by_id()

*根據(jù)標(biāo)簽編號查詢標(biāo)簽對象

*? \ < div

id = "box" > ...\ < / div >

*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)簽對象

*? \ < div

name = "real_name" >\ < / div >

*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)簽鏈接文本

擴(kuò)展

查詢標(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()

*鼠標(biāo)鏈操作

* 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)航前進(jìn)

*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)頁

*填寫賬號、密碼从铲,點擊登錄

*進(jìn)入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)系作者
  • 序言:七十年代末名段,一起剝皮案震驚了整個濱河市阱扬,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌伸辟,老刑警劉巖麻惶,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異信夫,居然都是意外死亡窃蹋,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進(jìn)店門静稻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來警没,“玉大人,你說我怎么就攤上這事振湾∩奔#” “怎么了?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵押搪,是天一觀的道長树酪。 經(jīng)常有香客問我,道長大州,這世上最難降的妖魔是什么续语? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮厦画,結(jié)果婚禮上绵载,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好娃豹,可當(dāng)我...
    茶點故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布焚虱。 她就那樣靜靜地躺著,像睡著了一般懂版。 火紅的嫁衣襯著肌膚如雪鹃栽。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天躯畴,我揣著相機(jī)與錄音民鼓,去河邊找鬼。 笑死蓬抄,一個胖子當(dāng)著我的面吹牛丰嘉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播嚷缭,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼饮亏,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了阅爽?” 一聲冷哼從身側(cè)響起路幸,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎付翁,沒想到半個月后简肴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡百侧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年砰识,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片佣渴。...
    茶點故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡仍翰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出观话,到底是詐尸還是另有隱情,我是刑警寧澤越平,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布频蛔,位于F島的核電站,受9級特大地震影響秦叛,放射性物質(zhì)發(fā)生泄漏晦溪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一挣跋、第九天 我趴在偏房一處隱蔽的房頂上張望三圆。 院中可真熱鬧,春花似錦、人聲如沸舟肉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽路媚。三九已至黄琼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間整慎,已是汗流浹背脏款。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留裤园,地道東北人撤师。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像拧揽,于是被迫代替她去往敵國和親剃盾。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,092評論 2 355

推薦閱讀更多精彩內(nèi)容