PhantomJs:無頭瀏覽器,支持JavaScript。(即包含Js引擎、瀏覽器排版引擎等核心組件,但是沒有和用戶交互的界面的瀏覽器。)
Selenium:WEB自動化測試工具。可以直接運行在瀏覽器中。不同瀏覽器提供不同的操作接口,Selenium通過這些接口來操作瀏覽器。
webdriver:Selenium的核心對象。通過它可以操作瀏覽器、截圖、http訪問、http解析等。
開發實例1:處理異步請求。在查詢
# 獲取bing查詢數據 # 通過異步請求返回結果,所以直接訪問頁面不能獲取到搜索結果。 from selenium import webdriver # 核心驅動對象 import datetime import time import random # 創建核心對象webdriver # mac系統下的文件路徑的斜杠與windows下的是相反的 driver = webdriver.PhantomJS(r'phantomjs-2.1.1-macosx/bin/phantomjs') # 指定PhantomJS的執行文件的路徑 # 設置分辨率 driver.set_window_size(1280, 2400) # 訪問的url url = 'https://cn.bing.com/search?q=%E7%8C%AB' driver.get(url) # 用get方法打開網頁,模擬瀏覽器地址欄輸入地址 # 截圖:保存圖片 def save_picture(): base_dir = 'picture/' file_name = '{}{:%Y%m%d%H%M%S}{}.png'.format(base_dir, datetime.datetime.now(), random.randint(1, 100)) driver.save_screenshot(file_name) # save_picture() # 訪問太快,會沒來得及加載動態頁面部分 # 方法1:等幾秒至頁面完全加載出來 # time.sleep(5) # print('*'*30) # save_picture() # 間隔5秒之后再次訪問,就可以獲得完全加載的頁面內容 # 方法2:在一定的重試次數內找到對應的標簽 MAXRETRYIES = 5 # 最大重試次數 while MAXRETRYIES: try: ele = driver.find_element_by_class_name('b_caption') # 找到需要等標簽元素即截圖保存 print(ele, MAXRETRYIES) save_picture() break except Exception as e: print(type(e)) # <class 'selenium.common.exceptions.NoSuchElementException'> print(e) # 捕獲錯誤 time.sleep(1) # 暫停一秒等頁面加載。 MAXRETRYIES -= 1 driver.close() # 同文件IO,要close
開發實例2:下拉框處理
from selenium import webdriver import datetime import random from selenium.webdriver.support.ui import Select #獲取有關select的包 driver = webdriver.PhantomJS(r'phantomjs-2.1.1-macosx/bin/phantomjs') # 指定PhantomJS的執行文件的路徑 driver.set_window_size(1280, 2400) # 設置窗口大小 # 保存圖片 def save_picture(): base_dir = 'picture/' file_name = '{}{:%Y%m%d%H%M%S}{}.png'.format(base_dir, datetime.datetime.now(), random.randint(1, 100)) driver.save_screenshot(file_name) url = "https://www.oschina.net/search?scope=project&q=python" driver.get(url) # 用get方法打開網頁,模擬瀏覽器地址欄輸入地址 # 處理select,想選擇tag1的第一項 ele = driver.find_element_by_class_name('tag1') # 獲取元素 print(ele.tag_name) print('current_url1:', driver.current_url) save_picture() s = Select(ele) # Select()處理的一定是select下拉框對象 s.select_by_index(1) # web應用開發 time.sleep(2) print('current_url2:', driver.current_url) save_picture() driver.close()
開發實例3:模擬鍵盤操作登錄網頁
from selenium import webdriver import datetime import time import random from selenium.webdriver.common.keys import Keys # 有關模擬鍵盤輸入的模塊 driver = webdriver.PhantomJS(r'phantomjs-2.1.1-macosx/bin/phantomjs') # 指定PhantomJS的執行文件的路徑 driver.set_window_size(1280, 2400) # 設置窗口大小 # 保存圖片 def save_picture(): base_dir = 'picture/' file_name = '{}{:%Y%m%d%H%M%S}{}.png'.format(base_dir, datetime.datetime.now(), random.randint(1, 100)) driver.save_screenshot(file_name) url = 'https://www.oschina.net/home/login' driver.get(url) print(driver.current_url) # https://www.oschina.net/home/login save_picture() # 獲取郵箱和密碼的2個輸入框對象 email = driver.find_element_by_id('userMail') pwd = driver.find_element_by_id('userPassword') # 模擬鍵盤輸入數據 username = '18390900259' password = '123456' email.send_keys(username) pwd.send_keys(password) print(driver.current_url) # https://www.oschina.net/home/login save_picture() pwd.send_keys(Keys.ENTER) # 回車=>登錄 time.sleep(1) # 登錄后頁面會有跳轉 print(driver.current_url) # https://www.oschina.net/?nocache=1553228140174 save_picture() while True: # 循環直到找到對應標簽對象 time.sleep(1) print(driver.current_url) try: userinfo = driver.find_element_by_class_name('user-info') print(userinfo.text) # 打印該標簽下的文本內容 save_picture() break except Exception as e: print(e) cookies = driver.get_cookies() # 獲取長期登陸的cookie print(cookies) print(cookies) driver.close() # 記得要關閉
開發實例4:頁面等待
越來越多的頁面使用Ajax的異步加載技術,會導致頁面中要被訪問的內容還沒加載就被訪問了,代碼拋出異常。
方法:
1.線程休眠:time.sleep(n)來等待數據加載。1.1:配合循環一直等到數據加載完成;1.2設置最大重試次數,避免一直循環下去。
2.Selenium等待:2.1:隱式等待:等待特定時間;2.2:顯式等待:指定一個條件,直到條件成立繼續往后執行。或者設置超時時間,超時拋出異常。
2.1隱式等待
from selenium import webdriver # 頁面隱式等待 driver = webdriver.PhantomJS(r'phantomjs-2.1.1-macosx/bin/phantomjs') driver.implicitly_wait(10) # 增加這一句,全局設置,會導致下面找元素等待10秒 url = "https://movie.douban.com/" driver.get(url) try: print('begin-------') ele = driver.find_element_by_id('abcde') # 在這里查找的時限為10秒,沒找到跳轉到except里 except Exception as e: print(type(e)) # <class 'selenium.common.exceptions.NoSuchElementException'> print(e, '~~~~~~~~~~') finally: driver.quit()
2.2顯式等待
# 定位搜索框,搜索電影 from selenium import webdriver # 核心對象 import datetime import random # 鍵盤操作 from selenium.webdriver.common.keys import Keys # WebDriverWait負責循環等待 from selenium.webdriver.support.wait import WebDriverWait # expected_conditions負責條件觸發 from selenium.webdriver.support import expected_conditions as ec from selenium.webdriver.common.by import By driver = webdriver.PhantomJS(r'phantomjs-2.1.1-macosx/bin/phantomjs') driver.set_window_size(1280, 2400) # 窗口大小 # 打開網頁,使用get方法 url = 'https://movie.douban.com/' driver.get(url) def save_picture(): base_dir = 'picture/' file_name = "{}{:%Y%m%d%H%M%S}{:03}.png".format(base_dir, datetime.datetime.now(), random.randint(1,100)) driver.save_screenshot(file_name) try: # 元素是否已加載到dom樹中;使用哪個driver,等到什么條件ok,ec就是等待的條件;expected有很多內置條件方法;20秒為超時時長,超時拋異常,超時時長內在try里默認0.5秒循環執行 ele = WebDriverWait(driver, 20).until( ec.presence_of_element_located((By.ID, 'inp-query')) # ex.presence_of_element_located(By.XPATH, '//input[@id="inp-query]' # 兩種不同的寫法:一個通過id查找元素,一個通過xpath
) ele.send_keys('TRON') # 加載出搜索框后,在搜索框內輸入'TRON',進行搜索 save_picture() ele.send_keys(Keys.ENTER) # 輸入回車鍵,開始搜索 print(driver.current_url) # 查看搜索后跳轉的url save_picture() finally: driver.quit() # 退出瀏覽器
WebDriver是Selenium的核心, 實現與瀏覽器的交互:打開URL,可以跟蹤跳轉,可以返回當前頁面的實際URL 獲取頁面的title;處理cookie 控制瀏覽器的操作,例如前進、后退、刷新、關閉,最大化等 執行JS腳本;在DOM中搜索頁面元素Web Element,指定的或一批,find系方法;操作網頁元素;模擬下拉框操作Select(element) 在元素上模擬鼠標操作click() 在元素上模擬鍵盤輸入send_keys() 獲取元素文字 text;獲取元素的屬性 get_attribute() 等等。