python中selenium使用

本文使用python3.6.5.

Selenium是一個用於Web應用程序測試的工具。

Selenium測試直接運行在瀏覽器中,就像真正的用戶在操作一樣。支持的瀏覽器包括IE(7, 8, 9, 10, 11),Firefox,Safari,Chrome,Opera等。

使用python爬蟲調用selenium來模擬正常用戶訪問瀏覽器.

Selenium和ChromeDriver的安裝與配置
安裝selenium:

win: pip install selenium
liunx: pip3 install selenium


安裝ChromeDriver, 該工具供selenium使用Chrome.

ChromeDriver: http://npm.taobao.org/mirrors/chromedriver/

下載前先查看本地環境的Chrome版本, 然後去上面的link中下載對應的ChromeDriver版本.

配置


將下載的ChromeDriver進行解壓.
將解壓後的文件放入合適的位置.
win: 將解壓後的文件放入配置了環境變量的文件夾, 如python的文件夾.
linux: 將解壓後的文件移動到/usr/loacl/bin目錄中.
完成.
簡單使用
如前面說的, 我們能使用python導入selenium來控制瀏覽器訪問網站.

也就是說能使用py打開瀏覽器自動化訪問.

Chrome有界面運行

#!/usr/bin/env python3
from selenium import werdriver
import time

driver = webdriver.Chrome()     # 創建Chrome對象.
# 操作這個對象.
driver.get('https://www.baidu.com')     # get方式訪問百度.
time.sleep(2)
driver.quit()   # 使用完, 記得關閉瀏覽器, 不然chromedriver.exe進程爲一直在內存中.


Chrome無界面運行

#!/usr/bin/env python3
'''
    根據chrome瀏覽器2017年發佈的新特性,
    需要unix版本的chrome版本高於57,
    windows版本的chrome版本高於58,
    才能使用無界面運行.
'''
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time


chrome_opt = Options()      # 創建參數設置對象.
chrome_opt.add_argument('--headless')   # 無界面化.
chrome_opt.add_argument('--disable-gpu')    # 配合上面的無界面化.
chrome_opt.add_argument('--window-size=1366,768')   # 設置窗口大小, 窗口大小會有影響.

# 創建Chrome對象並傳入設置信息.
driver = webdriver.Chrome(chrome_options=chrome_opt)        
# 操作這個對象.
driver.get('https://www.baidu.com')     # get方式訪問百度.
time.sleep(2)
print(driver.page_source)       # 打印加載的page code, 證明(prove) program is right.
driver.quit()   # 使用完, 記得關閉瀏覽器, 不然chromedriver.exe進程爲一直在內存中.


Selenium啓動項(參數設置)與Driver
Chrome WebDriver Options

#!/usr/bin/env python3
from selenium import webdriver
from selenium.webdriver.chrome.options import Options


chrome_opt = Options()      # 創建參數設置對象.
chrome_opt.add_argument('--windows-size=1366,768')  # 設置瀏覽器窗口大小.

# 創建chrome對象並傳入設置信息.
driver = webdriver.Chrome(chrome_options=chrome_opt)
driver.quit()


常用的啓動項

詳細的參數解釋: https://peter.sh/experiments/chromium-command-line-switches/

禁用圖片加載

Chrome的禁用圖片加載參數設置比較複雜,如下所示:

prefs = {
    'profile.default_content_setting_values' : {
        'images' : 2
    }
}
options.add_experimental_option('prefs',prefs)


禁用瀏覽器彈窗
使用瀏覽器時常常會有彈窗彈出,以下選項可以禁止彈窗:

prefs = {  
    'profile.default_content_setting_values' :  {  
        'notifications' : 2  
     }  
}  
options.add_experimental_option('prefs',prefs) 


Chrome WebDriver


chromedriver.exe一般可以放在環境文件中,但是有時候爲了方便部署項目,或者爲了容易打包,我們可以將chromedriver.exe放到我們的項目目錄中,然後在初始化Chrome Webdriver對象時,傳入chromedriver.exe的路徑。

from selenium import webdriver


driver = webdriver.Chrome(executable_path='chromedriver.exe')
driver.quit()


Selenium Driver操作
Driver對象常見操作


get(url): 在當前瀏覽器會話中訪問傳入的url地址, driver.get('https://www.baidu.com').

close(): 關閉瀏覽器當前窗口。

quit(): 退出webdriver並關閉所有窗口。

refresh(): 刷新當前頁面。

title: 獲取當前頁的標題。

page_source: 獲取當前頁渲染後的源代碼。

current_url: 獲取當前頁面的url。

window_handles: 獲取當前會話中所有窗口的句柄。

Driver查找單個元素

查找多個元素: 將其中的element加上一個s,則是對應的多個查找方法。

上面的方法都是將第一個找到的元素進行返回,而將所有匹配的元素進行返回使用的是find_elements_by_*方法。

Driver操作Cookie


add_cookie(cookie_dict) : 給當前會話添加一個cookie。

cookie_dict: 一個字典對象,必須要有”name”和”value”兩個鍵,可選的鍵有:“path”, “domain”, “secure”, “expiry” 。

用法:

driver.add_cookie({‘name’ : ‘foo’, ‘value’ : ‘bar’})
driver.add_cookie({‘name’ : ‘foo’, ‘value’ : ‘bar’, ‘path’ : ‘/’})
driver.add_cookie({‘name’ : ‘foo’, ‘value’ : ‘bar’, ‘path’ : ‘/’, ‘secure’:True})


get_cookie(name): 按name獲取單個Cookie,沒有則返回None。

get_cookies(): 獲取所有Cookie,返回的是一組字典。

delete_all_cookies(): 刪除所有Cookies。

delete_cookie(name): 按name刪除指定cookie。

Driver獲取截屏


get_screenshot_as_base64(): 獲取當前窗口的截圖保存爲一個base64編碼的字符串。
get_screenshot_as_file(filename): 獲取當前窗口的截圖保存爲一個png格式的圖片,filename參數爲圖片的保存地址,最後應該以.png結尾。如果出現IO錯誤,則返回False。
用法: driver.get_screenshot_as_file(‘/Screenshots/foo.png’)
get_screenshot_as_png(): 獲取當前窗口的截圖保存爲一個png格式的二進制字符串。


Driver獲取窗口信息


get_window_position(windowHandle=’current’): 獲取當前窗口的x,y座標。

get_window_rect(): 獲取當前窗口的x,y座標和當前窗口的高度和寬度。

get_window_size(windowHandle=’current’): 獲取當前窗口的高度和寬度。

 

Driver切換操作


switch_to_frame(frame_reference): 將焦點切換到指定的子框架中

switch_to_window(window_name): 切換窗口

 

Driver執行JS代碼


execute_async_script(script, *args) : 在當前的window/frame中異步執行JS代碼。

script:是你要執行的JS代碼。
*args:是你的JS代碼執行要傳入的參數。
用法:

script = “var callback = arguments[arguments.length - 1]; ”
script2 = “window.setTimeout(function(){ callback(‘timeout’) }, 3000);” 
driver.execute_async_script(script + script2)


execute_script(script, *args): 在當前的window/frame中同步執行JS代碼。

script:是你要執行的JS代碼。
*args:是你的JS代碼執行要傳入的參數。


Selenium Webelement操作
Webelement操作


前面有講到使用find等方法來查找單個或多個元素對象, 其結果返回一個Webelement對象.

Webelement常用方法


clear(): 清空對象中的內容.
click(): 單擊對象.
get_attribute(name): 優先返回完全匹配屬性名的值,如果不存在,則返回屬性名中包含name的值。
screenshot(filename): 獲取當前元素的截圖,保存爲png,最好用絕對路徑.
send_keys(value): 給對象元素輸入數據, 如在百度中搜索’嗶哩嗶哩’.
submit(): 提交表單.


Webelement常用屬性


text: 獲取當前元素的文本內容.
tag_name: 獲取當前元素的標籤名.
size: 獲取當前元素的大小.
screenshot_as_png: 將當前元素截屏並保存爲png格式的二進制數據.
screenshot_as_base64: 將當前元素截屏並保存爲base64編碼的字符串.
rect: 獲取一個包含當前元素大小和位置的字典.
parent: 獲取當前元素的父節點.
location: 當前元素的位置.
id: 當前元素的id值,主要用來selenium內部使用,可以用來判斷兩個元素是否是同一個元素.
Webelement中的keys
們經常需要模擬鍵盤的輸入,當輸入普通的值時,在send_keys()方法中傳入要輸入的字符串就好了。

但是我們有時候會用到一些特殊的按鍵,這時候就需要用到我們的Keys類。

# 要使用按鍵值, 需要導入下面keys.
from selenium.webdriver.common.keys import Keys

elem.send_keys(Keys.CONTROL, 'c')


Selenium Action-Chains


一般來說我們與頁面的交互可以使用Webelement的方法來進行點擊等操作。但是,有時候我們需要一些更復雜的動作,類似於拖動,雙擊,長按等等。

這時候就需要用到我們的Action Chains(動作鏈)了。

from selenium.webdriver import ActionChains
from selenium import webdriver

driver = webdriver.Chrome()     # 創建webdriver對象.

element = driver.find_element_by_name("source")     # 查找單一元素對象.
target = driver.find_element_by_name("target")      # 同上.

actions = ActionChains(driver)      # 創建動作鏈對象.

# 在element元素上點擊抓起,移動到target元素上鬆開放下。 類似鼠標.
actions.drag_and_drop(element, target)
actions.perform()   # 執行動作


在導入動作鏈模塊以後,需要聲明一個動作鏈對象,在聲明時將webdriver對象當作參數傳入,並將對象賦值給一個actions變量。

然後我們通過這個actions變量,調用其內部附帶的各種動作方法進行操作。

注:在調用各種動作方法後,這些方法並不會馬上執行,而是會按你代碼的順序存儲在ActionChains對象的隊列中。當你調用perform()時,這些動作纔會依次開始執行。

常用的Action-Chains方法
click(on_element=None) : 左鍵單擊傳入的元素,如果不傳入的話,點擊鼠標當前位置。
context_click(on_element=None): 右鍵單擊。
double_click(on_element=None) : 雙擊。
click_and_hold(on_element=None): 點擊並抓起
drag_and_drop(source, target) : 在source元素上點擊抓起,移動到target元素上鬆開放下。
drag_and_drop_by_offset(source, xoffset, yoffset):在source元素上點擊抓起,移動到相對於source元素偏移xoffset和yoffset的座標位置放下。
send_keys(*keys_to_send): 將鍵發送到當前聚焦的元素。
send_keys_to_element(element, *keys_to_send): 將鍵發送到指定的元素。
reset_actions(): 清除已經存儲的動作。


Selenium Wait
爲什麼需要等待?


在selenium操作瀏覽器的過程中,每一次請求url,selenium都會等待頁面加載完畢以後,纔會將操作權限再次交給我們的程序。

但是,由於ajax和各種JS代碼的異步加載問題,所以我們在使用selenium的時候常常會遇到操作的元素還沒有加載出來,就會引發報錯。爲了解決這個問題,Selenium提供了幾種等待的方法,讓我們可以等待元素加載完畢後,再進行操作。

 顯式等待.

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


driver = webdriver.Chrome()
driver.get("http://somedomain/url_that_delays_loading")

try:
    # 創建wait對象.
    element = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.ID, "myDynamicElement"))
    )

finally:
    driver.quit()


在這個例子中,我們在查找一個元素的時候,不再使用find_element_by_*這樣的方式來查找元素,而是使用了WebDriverWait。

try代碼塊中的代碼的意思是:在拋出元素不存在異常之前,最多等待10秒。在這10秒中,WebDriverWait會默認每500ms運行一次until之中的內容,而until中的EC.presence_of_element_located則是檢查元素是否已經被加載,檢查的元素則通過By.ID這樣的方式來進行查找。

就是說,在10秒內,默認每0.5秒檢查一次元素是否存在,存在則將元素賦值給element這個變量。如果超過10秒這個元素仍不存在,則拋出超時異常。

隱式等待.
隱式等待指的是,在webdriver中進行find_element這一類查找操作時,如果找不到元素,則會默認的輪詢等待一段時間。

這個值默認是0,可以通過以下方式進行設置:

from selenium import webdriver

driver = webdriver.Chrome()
driver.implicitly_wait(10) # 單位是秒
driver.get("http://somedomain/url_that_delays_loading")
myDynamicElement = driver.find_element_by_id("myDynamicElement")

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章