selenium是一套web網站自動化測試工具,主要經過命令行的操做完成常規可視化界面下的用戶各類操做行爲,由於其簡單易學成本低,而且執行測試效率較高而在web自動化測試方面比較突出,該庫能夠直接運行操做各類主流瀏覽器,輔助瀏覽器自動完成表單互動、鼠標點擊、鼠標拖拽、窗口切換等等各類用戶行爲,是一套很是好用且強大的測試庫,可是selenium沒有內置的瀏覽器模塊,不能獨立運行,必需要和第三方瀏覽器配合使用才能夠完成自動化測試操做。css
在實際操做的過程當中,常用selenium和各大主流瀏覽器共同操做,如谷歌、火狐、IE等等,可是在selenium自動化測試發展過程當中,有一個特殊的瀏覽器常常用於和它配合使用,就是比較出名的無界面瀏覽器phantomJS。html
這時候問題就來了,爬蟲中,爲何要涉及到selenium測試工具和無界面瀏覽器這樣的東東呢?python
說來話長了web
故事背景:那是好久的之前,人們生活在一個很是平和的年代api
老李住在人民小區的一所豪宅中,人人互愛互助,路不拾遺夜不閉戶已經成了傳統瀏覽器
這天,從遙遠的他鄉來了一我的~老王(爬蟲),禁不住五臟廟的鬧騰,終於決定要找點吃的了,他一路獨行直接進來了老李家,把老李留給媳婦的無骨燉雞湯給吃了個精光,而後施施然瀟灑的離去了..
[爬蟲老王,根據本身須要的數據對於網站服務器老李進行了數據採集,服務器沒有任何防範,數據直接被獲取到了!]安全
老李終於回家了,發現有人動了他的雞湯....因而,晚上老李家傳來了老李的慘叫聲.
老李吸收教訓,應該是有小區以外的人進了小區,因而跟守門大媽說了一句,之後進門的人必定要問問有木有門卡(備註:門卡是小區住戶纔有的一種身份卡片),有卡才讓進小區,不然不容許進入
[服務器老李因爲數據無故泄露致使出現了安全問題,因而進行了簡單的升級防範,針對全部進行訪問的用戶驗證其User-agent,若是User-agent不合適則禁止訪問]服務器
老王這天又餓的不行了,可是進小區時發現大媽居然要查牌,好吧,老王找到小區的某我的,請它吃了頓飯,順便看了看門卡長的什麼樣子,而後本身偷偷去作了一張如出一轍的卡片,而後 老王又進去了老李家,半夜小區又傳來了老李的慘叫~~
[爬蟲老王經過抓包工具進行了服務器請求的抓包,分析了請求中的各項參數,在請求頭中添加了瀏覽器的User-agent的值,再次訪問服務器,順利拿到了須要採集的數據]cookie
老李憤慨於老王的行爲,再次跟門口大媽說了說,家裏的東西又被人動了,大媽回憶了一下這幾天的狀況,發現老王頻繁的進入小區,因而大媽針對天天頻繁進入小區的人單獨進行了登記,注意防範,一旦出現就堅定不容許這樣的人再進入小區
[服務器老李針對再次數據泄露,認識到了可能有非法用戶屢次採集數據形成的,因而針對限定時間頻繁訪問數據的操做進行了屏蔽,若是出現1分鐘內訪問次數超過30次的直接屏蔽ip地址]異步<> -------------
老王這天來到小區門口,發現和他同樣的老孫餓的皮包骨頭,很詫異的問老孫什麼狀況,老孫據實說了實際狀況,老孫已經進了大媽的黑名單,不再能進小區覓食了!老王發現了這個問題以後,因而~天天只進入一次小區,還跟大媽很熱情的打招呼呢.....老李是完全的憤怒了,家裏的吃的雖然沒有像以前丟的那麼頻繁,可是終歸仍是丟了特別重要的部分,半夜時分,老李的慘叫是那麼的慘絕人寰[爬蟲老王限制了爬蟲訪問服務器的時間,根據正經常使用戶的發送請求的時間,限制了不一樣爬取請求之間的休眠時間,儘管採集數據較慢,可是一樣獲得了數據]<> -------------
老李此次學乖了,出門的時候給家裏上鎖了,在也不愁數據數據再次丟失的問題了[服務器老李在請求參數中,添加了一個加密字段,若是參數中包含了正確的加密字段,就容許訪問數據,若是參數中沒有標註則拒絕訪問]
老王已經餓了太多天了
老王找到了傳說中的某個大師,跟他學了曠古絕技,因而在某個豔陽高照的晴天,再次進了老李家....這天半夜,老李默默的坐了一個晚上[爬蟲針對加密數據進行了分析追蹤,獲得了加密 的具體流程,因而進行了加密字段的重現,將加密數據經過請求傳遞給了服務器,順利獲取到了數據]
<> -------------
老李根據本身的須要,換了指紋密碼鎖[服務器針對數據安全問題,進行了再次升級,對數據進行了混淆編碼的同時,經過混淆編碼進行了多重加密操做,同時進行了多個字段的數字指紋簽名操做,若是請求中不包含這些數據的狀況下,拒絕提供數據]<>-------------
老王看着緊鎖的大門,想了好久....這天老李家來了客人,好酒好菜兩人暢談甚久,夜幕時分,老王施施然從老李家走了出來,身旁就是老李相送[客戶端老王看到服務器老李已經作了很是複雜的反爬蟲操做,因而權衡以後再也不作反扒操做,直接讓本身變成了正式用戶發送請求,一樣獲取到了數據]
而這裏涉及到的正式用戶的請求,就是直接經過瀏覽器發送請求訪問服務器,用到的瀏覽器就是phantomJS無界面瀏覽器,經過selenium測試工具發送請求操做訪問過程獲取數據
準備工做:selenium和PhantomJS
phantomjs:一個獨立的無界面瀏覽器,並非python模塊,因此須要單獨下載安裝;phantomjs官方網站:http://phantomjs.org/
selenium:獨立的第三方模塊,經過pip install selenium
進行安裝
selenium.webdriver
find_element_by_id()
find_elements_by_name()
find_elemnets_by_xpath()
find_elements_by_link_text()
find_elemetns_by_partial_link_text()
find_elements_by_tag_name()
find_elements_by_class_name()
find_elements_by_css_selector()
selenium.webdirver.common.keys.Keys
selenium.webdriver.ActionChains
頁面窗口操做
cookie操做
網頁延時:針對網頁中經過Ajax異步加載Json數據的狀況,不一樣的網速下返回Json數據並渲染頁面會有延遲,網頁中並不必定能正常獲取數據,須要延時操做
# 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: # 獲取標籤:間隔10S獲取標籤~一直等待到標籤獲取成功 element = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "box")) ) finally: driver.quit()
這裏的等待條件,就是except_conditions
調用時執行的函數,內置以下條件能夠直接調用
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
# 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場景:
selenium配合phantomjs完成登陸操做,並保存數據到文件中
# 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") # 保存數據 with open("csdn.html", "w") as f: f.write(driver.page_source.encode("utf-8")) # 退出瀏覽器 driver.quit()