Python Selenium 常用功能(實戰詳解)


一、Python+Selenium配置

  • 前提條件: 已安裝好Python開發環境,版本3.5以上
  • 安裝步驟:

1.1 打開cmd 輸入pip install selenium 點擊回車鍵,具體如下圖

在這里插入圖片描述
在這里插入圖片描述

1.2 把下載好的chromedriver.exe放到Python安裝目錄下,下載方法

二、啟動瀏覽器

2.1 普通啟動方式

#!/usr/bin/python3
# encoding:utf-8
from selenium  import webdriver

#啟動Firefox瀏覽器
#browser = webdriver.Firefox()
#啟動IE瀏覽器
#browser = webdriver.Ie()
#啟動Chrome瀏覽器
#指定驅動方式啟動:webdriver.Chrome(executable_path="D://chromedriver.exe")
browser = webdriver.Chrome()
browser.get("http://www.baidu.com")

2.2 Headless啟動方式

說明:瀏覽器的無界面形態,無需打開瀏覽器即可運行,此種方式只chrome60+版本

#!/usr/bin/python3
# encoding:utf-8
from selenium import webdriver

chrome_hless = webdriver.ChromeOptions()
# 使用headless無界面瀏覽器模式
chrome_hless.add_argument('--headless') 
chrome_hless.add_argument('--disable-gpu') 

# 啟動瀏覽器,獲取網頁源代碼
browser = webdriver.Chrome(chrome_options=chrome_hless)
mainUrl = "https://www.baidu.com/"
browser.get(mainUrl)
print(browser.title)
browser.quit()

''' 
運行之后結果打印百度標題:
百度一下,你就知道
''' 

三、元素定位

元素 定位方法
id find_element_by_id()
name find_element_by_name()
class find_element_by_class_name()
link_text find_element_by_link_text("全部文字匹配")
partial_link_text find_element_by_partial_link_text("部分文字匹配")
tag find_element_by_tag_name()
xpath find_element_by_xpath()
css find_element_by_css_selector()

詳見Python + Selenium 元素定位詳細

四、selenium三種等待方式

4.1 強制等待

固定等待XX秒時長

   from selenium import webdriver
   import time
   time.sleep(3) 

4.2 隱性等待

設置最長等待時長XX秒:

  • 第一種情況:最長等待時長內瀏覽器一旦加載完成,直接進行下一步操作
  • 第二種情況:超出設置最長等待時長,再進行下一步操作
# 瀏覽器加載完成,即進行下一步操作,如果10秒鍾還未加載完成,也進行下一步操作
driver.implicitly_wait(10)  

4.3 顯性等待

WebDriverWait,配合該類的until()和until_not()方法,就能夠根據判斷條件而進行靈活地等待了。它主要的意思就是:程序每隔xx秒看一眼,如果條件成立了,則執行下一步,否則繼續等待,直到超過設置的最長時間,然后拋出TimeoutException

wait模塊的WebDriverWait類是顯性等待類,先看下它有哪些參數與方法:

selenium.webdriver.support.wait.WebDriverWait(類)
init

driver: 傳入WebDriver實例,即我們上例中的driver
timeout: 超時時間,等待的最長時間(同時要考慮隱性等待時間)
poll_frequency: 調用until或until_not中的方法的間隔時間,默認是0.5秒
ignored_exceptions: 忽略的異常,如果在調用until或until_not的過程中拋出這個元組中的異常,則不中斷代碼,繼續等待,如果拋出的是這個元組外的異常,則中斷代碼,拋出異常。默認只有NoSuchElementException。

until

method: 在等待期間,每隔一段時間(__init__中的poll_frequency)調用這個傳入的方法,直到返回值不是False
message: 如果超時,拋出TimeoutException,將message傳入異常

until_not

與until相反,until是當某元素出現或什么條件成立則繼續執行,
until_not是當某元素消失或什么條件不成立則繼續執行,參數也相同,不再贅述。

具如下

WebDriverWait(driver, 超時時長, 調用頻率, 忽略異常).until(可執行方法, 超時時返回的信息)

特別注意的是until或until_not中的可執行方法method參數,很多人傳入了WebElement對象,如下:

WebDriverWait(driver, 10).until(driver.find_element_by_id('kw')) # 錯誤

這是錯誤的用法,這里的參數一定要是可以調用的,即這個對象一定有 call() 方法,否則會拋出異常:

TypeError: 'xxx' object is not callable
在這里,你可以用selenium提供的 expected_conditions 模塊中的各種條件,也可以用WebElement的 is_displayed() 、is_enabled()、**is_selected() **方法,或者用自己封裝的方法都可以

WebDriverWait 常用方法表

對象 動作
title_is 判斷當前頁面的title是否完全匹配
title_contains 判斷當前頁面的title是否包含預期字符串
presence_of_element_located 判斷某個元素是否被加到了dom樹里,並不代表該元素一定可見
visibility_of_element_located 判斷某個元素是否可見.可見代表元素非隱藏,並且元素的寬和高都不等於0
visibility_of 跟上面的方法做一樣的事情,只是上面的方法要傳入locator,這個方法直接傳定位到的element就好了
presence_of_all_elements_located 判斷是否至少有1個元素存在於dom樹中。舉個例子,如果頁面上有n個元素的class都是'column-md-3',那么只要有1個元素存在,這個方法就返回True
text_to_be_present_in_element 判斷某個元素中的text是否包含了預期的字符串
text_to_be_present_in_element_value 判斷某個元素中的value屬性是否包含了預期的字符串
frame_to_be_available_and_switch_to_it 判斷該frame是否可以switch進去,如果可以的話,返回True並且switch進去,否則返回False
invisibility_of_element_located 判斷某個元素中是否不存在於dom樹或不可見
element_to_be_clickable 判斷某個元素中是否可見並且是enable的,這樣的話才叫clickable
staleness_of 等某個元素從dom樹中移除,注意,這個方法也是返回True或False
element_to_be_selected 判斷某個元素是否被選中了,一般用在下拉列表
element_selection_state_to_be 判斷某個元素的選中狀態是否符合預期
element_located_selection_state_to_be 跟上面的方法作用一樣,只是上面的方法傳入定位到的element,而這個方法傳入locator
alert_is_present 判斷頁面上是否存在alert

源碼舉例

#coding=utf-8
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

base_url = "http://www.baidu.com"
driver = webdriver.Chrome()
driver.implicitly_wait(5)
'''隱式等待和顯示等待都存在時,超時時間取二者中最大的'''
locator = (By.ID,'kw')
driver.get(base_url)

'''判斷title是否存在,返回布爾值'''
WebDriverWait(driver,10).until(EC.title_is(u"百度一下,你就知道"))
if WebDriverWait(driver,10).until(EC.title_is(u"百度一下,你就知道")) :
    print("已找到標題百度一下,你就知道")
WebDriverWait(driver,10).until(EC.title_contains(u"百度一下"))

'''判斷某個元素是否被加到了dom樹里,並不代表該元素一定可見,如果定位到就返回WebElement'''
srk = WebDriverWait(driver,10).until(EC.presence_of_element_located((By.ID,'kw')))
#百度輸入框,輸入selenim
srk.send_keys("selenim")

'''判斷某個元素是否被添加到了dom里並且可見,可見代表元素可顯示且寬和高都大於0'''
WebDriverWait(driver,10).until(EC.visibility_of_element_located((By.ID,'su')))

'''判斷元素是否可見,如果可見就返回這個元素WebElement'''
WebDriverWait(driver,10).until(EC.visibility_of(driver.find_element(by=By.ID,value='kw')))

'''判斷是否至少有1個元素存在於dom樹中,如果定位到就返回WebElement列表'''
WebDriverWait(driver,10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR,'.mnav')))

'''判斷是否至少有一個元素在頁面中可見,如果定位到就返回WebElement列表'''
WebDriverWait(driver,10).until(EC.visibility_of_any_elements_located((By.CSS_SELECTOR,'.mnav')))

'''判斷指定的元素中是否包含了預期的字符串,返回布爾值'''
WebDriverWait(driver,10).until(EC.text_to_be_present_in_element((By.XPATH,"//*[@id='u1']/a[8]"),u'設置'))

'''判斷指定元素的屬性值中是否包含了預期的字符串,返回布爾值'''
WebDriverWait(driver,10).until(EC.text_to_be_present_in_element_value((By.CSS_SELECTOR,'#su'),u'百度一下'))

'''判斷該frame是否可以switch進去,如果可以的話,返回True並且switch進去,否則返回False'''
#WebDriverWait(driver,10).until(EC.frame_to_be_available_and_switch_to_it(locator))
#注意這里並沒有一個frame可以切換進去

'''判斷某個元素在是否存在於dom或不可見,如果可見返回False,不可見返回這個元素'''
WebDriverWait(driver,10).until(EC.invisibility_of_element_located((By.CSS_SELECTOR,'#swfEveryCookieWrap')))
#注意#swfEveryCookieWrap在此頁面中是一個隱藏的元素

'''判斷某個元素中是否可見並且是enable的,代表可點擊'''
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//*[@id='u1']/a[8]"))).click()
driver.find_element_by_xpath("//*[@id='wrapper']/div[6]/a[1]").click()
'''等待某個元素從dom樹中移除'''
#WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//*[@id='wrapper']/div[6]/a[1]"))).click()
#WebDriverWait(driver,10).until(EC.staleness_of(driver.find_element(By.ID,'su')))
#這里沒有找到合適的例子

'''判斷某個元素是否被選中了,一般用在下拉列表'''
WebDriverWait(driver,10).until(EC.element_to_be_selected(driver.find_element(By.XPATH,"//*[@id='nr']/option[1]")))

'''判斷某個元素的選中狀態是否符合預期'''
WebDriverWait(driver,10).until(EC.element_selection_state_to_be(driver.find_element(By.XPATH,"//*[@id='nr']/option[1]"),True))

'''判斷某個元素的選中狀態是否符合預期'''
WebDriverWait(driver,10).until(EC.element_located_selection_state_to_be((By.XPATH,"//*[@id='nr']/option[1]"),True))
driver.find_element_by_xpath(".//*[@id='gxszButton']/a[1]").click()

'''判斷頁面上是否存在alert,如果有就切換到alert並返回alert的內容'''
instance = WebDriverWait(driver,10).until(EC.alert_is_present())
print(instance.text)
instance.accept()

driver.close()


五、瀏覽器操作

5.1 將瀏覽器最大化顯示

browser.maximize_window()

5.2 將瀏覽器最小化顯示

browser.minimize_window()

5.3 設置瀏覽器寬1366、高768顯示

browser.set_window_size(1366, 768)

5.4 瀏覽器前進、后退、退出、關閉

browser.forword()#前進
browser.back()#后退
browser.quit()#退出
browser.close()#關閉

六、.操作元素對象

對象- 動作
clear() 清空
send_keys() 鍵盤操作
click() 點擊
submit() 提交
text 獲取對象文本
get_attribute() 獲取對象屬性值

源碼舉例

#coding=utf-8
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

base_url = "http://www.baidu.com"

driver = webdriver.Chrome()
driver.get(base_url)
driver.implicitly_wait(5)
#clear() 清空
driver.find_element(By.ID,'kw').clear()

#send_keys()輸入框鍵盤輸入select
driver.find_element(By.ID,'kw').send_keys("select")

#click()點擊對象
driver.find_element(By.ID,'su').click()

#submit()提交,注意類型type=‘submit’
driver.find_element(By.ID,'su').submit()

#text獲取元素文本值
button_name = driver.find_element_by_id('su').text

#get_attribute("type") 獲取屬性值
button_type = driver.find_element_by_id('su').get_attribute("type")
if button_type == "submit":
    print("type為submit")

七、鍵盤事件

對象 動作
send_keys(Keys.TAB) TAB
send_keys(Keys.ENTER) 回車
send_keys(Keys.F12) F12
send_keys(Keys.CONTROL,'a') ctrl+a

源碼舉例

#coding=utf-8
from selenium import webdriver
import time
#鍵盤操作必須輸入包
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome()
driver.get("http://www.baidu.com")
driver.implicitly_wait(5)

bdsrk = driver.find_element_by_id('kw')
bdsrk.send_keys('輸入')

#TAB
bdsrk.send_keys(Keys.TAB)
time.sleep(3)

#回車
bdsrk.send_keys(Keys.ENTER)
time.sleep(3)

#ctrl+a 全選輸入框內容 
driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'a')
time.sleep(3)

#F12
bdsrk.send_keys(Keys.F12)
driver.close()

八、.鼠標事件

對象 動作
click 單擊
context_click() 右擊
double_click() 雙擊
drag_and_drop() 拖動
move_to_element() 鼠標懸停
click_and_hold 按下鼠標左鍵在一個元素上

源碼舉例

#coding=utf-8
from selenium import webdriver
import time
#鼠標操作必須輸入包
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Chrome()
driver.get("http://www.baidu.com")
driver.implicitly_wait(5)

bdsrk  = driver.find_element_by_id('kw')
#百度一下按鈕
bdan = driver.find_element_by_id('su')

#視頻鏈接
dt =driver.find_element_by_name("tj_trtieba")
time.sleep(3)

#單擊
bdsrk.click()
time.sleep(3)

#右擊
ActionChains(driver).context_click(bdsrk).perform()
time.sleep(3)

#雙擊
ActionChains(driver).double_click(bdan).perform()
time.sleep(3)

#鼠標拖放 從百度一下按鈕拖動到新聞鏈接位置
ActionChains(driver).drag_and_drop(bdan,dt)
time.sleep(3)

#鼠標懸停
ActionChains(driver).move_to_element(dt).perform()
time.sleep(3)
driver.close()

九、.多層框架/層級定位

定位元素過程中經常會遇到找不到元素的問題,出現該問題一般都是以下因素導致:

  • 元素定位方法不對
  • 頁面存在iframe或內嵌窗口
  • 頁面超時
    webdriver 提供了一個 switch_to_frame 方法,可以很輕松的來解決這個問題。
#先找到到 ifrome1(id = from1)
browser.switch_to_frame("from1")

十、Selenium速查表

異常 描述
WebDriverException 所有webdriver異常的基類,當有異常且不屬於下列異常時拋出
InvalidSwitchToTargetException 下面兩個異常的父類,當要switch的目標不存在時拋出
NoSuchFrameException 當你想要用switch_to.frame()切入某個不存在的frame時拋出
NoSuchWindowException 當你想要用switch_to.window()切入某個不存在的window時拋出
NoSuchElementException 元素不存在,一般由find_element與find_elements拋出
NoSuchAttributeException 一般你獲取不存在的元素屬性時拋出,要注意有些屬性在不同瀏覽器里是有不同的屬性名的
StaleElementReferenceException 指定的元素過時了,不在現在的DOM樹里了,可能是被刪除了或者是頁面或iframe刷新了
UnexpectedAlertPresentException 出現了意料之外的alert,阻礙了指令的執行時拋出
NoAlertPresentException 你想要獲取alert,但實際沒有alert出現時拋出
InvalidElementStateException 下面兩個異常的父類,當元素狀態不能進行想要的操作時拋出
ElementNotVisibleException 元素存在,但是不可見,不可以與之交互
ElementNotSelectableException 當你想要選擇一個不可被選擇的元素時拋出
InvalidSelectorException 一般當你xpath語法錯誤的時候拋出這個錯
InvalidCookieDomainException 當你想要在非當前url的域里添加cookie時拋出
UnableToSetCookieException 當driver無法添加一個cookie時拋出
TimeoutException 當一個指令在足夠的時間內沒有完成時拋出
MoveTargetOutOfBoundsException actions的move操作時拋出,將目標移動出了window之外
UnexpectedTagNameException 獲取到的元素標簽不符合要求時拋出,比如實例化Select,你傳入了非select標簽的元素時
ImeNotAvailableException 輸入法不支持的時候拋出,這里兩個異常不常見,ime引擎據說是僅用於linux下對中文/日文支持的時候
ImeActivationFailedException 激活輸入法失敗時拋出
ErrorInResponseException 不常見,server端出錯時可能會拋出
RemoteDriverServerException 不常見,好像是在某些情況下驅動啟動瀏覽器失敗的時候會報這個錯


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM