2萬(wàn)字帶你了解Selenium全攻略
??????關(guān)注我,和老表一起學(xué)Python、云服務(wù)器
大家好,我是老表~
今天帶大家一起學(xué)(復(fù))習(xí)模擬瀏覽器運(yùn)行的庫(kù)Selenium,它是一個(gè)用于Web應(yīng)用程序測(cè)試的工具。Selenium測(cè)試直接運(yùn)行在瀏覽器中,就像真正的用戶在操作一樣。支持的瀏覽器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera和Edge等。
這里我將以Chrome為例進(jìn)行Selenium功能的演示~
目錄:
0. 準(zhǔn)備工作
0.1. 安裝selenium庫(kù)
0.2. 安裝瀏覽器驅(qū)動(dòng)
1. 基本用法
1.1. 初始化瀏覽器對(duì)象
1.2. 訪問(wèn)頁(yè)面
1.3. 設(shè)置瀏覽器大小
1.4. 刷新頁(yè)面
1.5. 前進(jìn)后退
2. 獲取頁(yè)面基礎(chǔ)屬性
3. 定位頁(yè)面元素
3.1. id定位
3.2. name定位
3.3. class定位
3.4. tag定位
3.5. link定位
3.6. partial定位
3.7. xpath定位
3.8. css定位
3.9. find_element的By定位
3.10. 多個(gè)元素
4. 獲取頁(yè)面元素屬性
4.1. get_attribute獲取屬性
4.2. 獲取文本
4.3. 獲取其他屬性
5. 頁(yè)面交互操作
5.1. 輸入文本
5.2. 點(diǎn)擊
5.3. 清除文本
5.4. 回車確認(rèn)
5.5. 單選
5.6. 多選
5.7. 下拉框
6. 多窗口切換
6.1. Frame切換
6.2. 選項(xiàng)卡切換
7. 模擬鼠標(biāo)操作
7.1. 左鍵
7.2. 右鍵
7.3. 雙擊
7.4. 拖拽
7.5. 懸停
8. 模擬鍵盤(pán)操作
9. 延時(shí)等待
9.1. 強(qiáng)制等待
9.2. 隱式等待
9.3. 顯式等待
10. 其他
10.1. 運(yùn)行JavaScript
10.2. Cookie
10.3. 反屏蔽
0. 準(zhǔn)備工作
在開(kāi)始后續(xù)功能演示之前,我們需要先安裝Chrome瀏覽器并配置好ChromeDriver,當(dāng)然也需要安裝selenium庫(kù)!
0.1. 安裝selenium庫(kù)
pip install selenium
0.2. 安裝瀏覽器驅(qū)動(dòng)
其實(shí),有兩種方式安裝瀏覽器驅(qū)動(dòng):一種是常見(jiàn)的手動(dòng)安裝,另一種則是利用第三方庫(kù)自動(dòng)安裝。
以下前提:大家都已經(jīng)安裝好了Chrome瀏覽器哈
手動(dòng)安裝
先查看本地Chrome瀏覽器版本:(兩種方式均可)
在瀏覽器的地址欄鍵入 Chrome://version,即可查看瀏覽器版本號(hào)
或者點(diǎn)擊 Chrome菜單 幫助→關(guān)于Google Chrome,查看瀏覽器版本號(hào)
再選擇對(duì)應(yīng)版本號(hào)的驅(qū)動(dòng)版本
下載地址:https://chromedriver.storage.googleapis.com/index.html
最后進(jìn)行環(huán)境變量配置,也就是將對(duì)應(yīng)的ChromeDriver的可執(zhí)行文件chromedriver.exe文件拖到Python的Scripts目錄下。
注:當(dāng)然也可以不這樣做,但是在調(diào)用的時(shí)候指定chromedriver.exe絕對(duì)路徑亦可。
自動(dòng)安裝
自動(dòng)安裝需要用到第三方庫(kù)webdriver_manager,先安裝這個(gè)庫(kù),然后調(diào)用對(duì)應(yīng)的方法即可。
from?selenium?import?webdriver
from?selenium.webdriver.common.keys?import?Keys
from?webdriver_manager.chrome?import?ChromeDriverManager
browser?=?webdriver.Chrome(ChromeDriverManager().install())
browser.get('http://www.baidu.com')
search?=?browser.find_element_by_id('kw')
search.send_keys('python')
search.send_keys(Keys.ENTER)
#?關(guān)閉瀏覽器
browser.close()
在上述代碼中,ChromeDriverManager().install()方法就是自動(dòng)安裝驅(qū)動(dòng)的操作,它會(huì)自動(dòng)獲取當(dāng)前瀏覽器的版本并去下載對(duì)應(yīng)的驅(qū)動(dòng)到本地。
====== WebDriver manager ======
Current google-chrome version is 96.0.4664
Get LATEST chromedriver version for 96.0.4664 google-chrome
There is no [win32] chromedriver for browser in cache
Trying to download new driver from https://chromedriver.storage.googleapis.com/96.0.4664.45/chromedriver_win32.zip
Driver has been saved in cache [C:\Users\Gdc\.wdm\drivers\chromedriver\win32\96.0.4664.45]
如果本地已經(jīng)有該瀏覽器渠道,則會(huì)提示其已存在。
======?WebDriver?manager?======
Current?google-chrome?version?is?96.0.4664
Get?LATEST?driver?version?for?96.0.4664
Driver?[C:\Users\Gdc\.wdm\drivers\chromedriver\win32\96.0.4664.45\chromedriver.exe]?found?in?cache

搞定以上準(zhǔn)備工作,我們就可以開(kāi)始本文正式內(nèi)容的學(xué)習(xí)啦~
1. 基本用法
這節(jié)我們就從初始化瀏覽器對(duì)象、訪問(wèn)頁(yè)面、設(shè)置瀏覽器大小、刷新頁(yè)面和前進(jìn)后退等基礎(chǔ)操作。
1.1. 初始化瀏覽器對(duì)象
在準(zhǔn)備工作部分我們提到需要將瀏覽器渠道添加到環(huán)境變量或者指定絕對(duì)路徑,前者可以直接初始化后者則需要進(jìn)行指定。
from?selenium?import?webdriver
#?初始化瀏覽器為chrome瀏覽器
browser?=?webdriver.Chrome()
#?指定絕對(duì)路徑的方式
path?=?r'C:\Users\Gdc\.wdm\drivers\chromedriver\win32\96.0.4664.45\chromedriver.exe'
browser?=?webdriver.Chrome(path)
#?關(guān)閉瀏覽器
browser.close()

可以看到以上是有界面的瀏覽器,我們還可以初始化瀏覽器為無(wú)界面的瀏覽器。
from?selenium?import?webdriver
#?無(wú)界面的瀏覽器
option?=?webdriver.ChromeOptions()
option.add_argument("headless")
browser?=?webdriver.Chrome(options=option)
#?訪問(wèn)百度首頁(yè)
browser.get(r'https://www.baidu.com/')
#?截圖預(yù)覽
browser.get_screenshot_as_file('截圖.png')
#?關(guān)閉瀏覽器
browser.close()

完成瀏覽器對(duì)象的初始化后并將其賦值給了browser對(duì)象,接下來(lái)我們就可以調(diào)用browser來(lái)執(zhí)行各種方法模擬瀏覽器的操作了。
1.2. 訪問(wèn)頁(yè)面
進(jìn)行頁(yè)面訪問(wèn)使用的是get方法,傳入?yún)?shù)為待訪問(wèn)頁(yè)面的URL地址即可。
from?selenium?import?webdriver
#?初始化瀏覽器為chrome瀏覽器
browser?=?webdriver.Chrome()
#?訪問(wèn)百度首頁(yè)
browser.get(r'https://www.baidu.com/')
#?關(guān)閉瀏覽器
browser.close()

1.3. 設(shè)置瀏覽器大小
set_window_size()方法可以用來(lái)設(shè)置瀏覽器大小(就是分辨率),而maximize_window則是設(shè)置瀏覽器為全屏!
from?selenium?import?webdriver
import?time??
browser?=?webdriver.Chrome()
#?設(shè)置瀏覽器大小:全屏
browser.maximize_window()???
browser.get(r'https://www.baidu.com')??
time.sleep(2)
#?設(shè)置分辨率?500*500
browser.set_window_size(500,500)??
time.sleep(2)
#?設(shè)置分辨率?1000*800
browser.set_window_size(1000,800)?
time.sleep(2)
#?關(guān)閉瀏覽器
browser.close()
這里就不截圖了,大家自行演示看效果哈~
1.4. 刷新頁(yè)面
刷新頁(yè)面是我們?cè)跒g覽器操作時(shí)很常用的操作,這里refresh()方法可以用來(lái)進(jìn)行瀏覽器頁(yè)面刷新。
from?selenium?import?webdriver
import?time??
browser?=?webdriver.Chrome()
#?設(shè)置瀏覽器全屏
browser.maximize_window()???
browser.get(r'https://www.baidu.com')??
time.sleep(2)
try:
????#?刷新頁(yè)面
????browser.refresh()??
????print('刷新頁(yè)面')
except?Exception?as?e:
????print('刷新失敗')
???
#?關(guān)閉瀏覽器
browser.close()
大家也是自行演示看效果哈,同F5快捷鍵。
1.5. 前進(jìn)后退
前進(jìn)后退也是我們?cè)谑褂脼g覽器時(shí)非常常見(jiàn)的操作,這里forward()方法可以用來(lái)實(shí)現(xiàn)前進(jìn),back()可以用來(lái)實(shí)現(xiàn)后退。
from?selenium?import?webdriver
import?time??
browser?=?webdriver.Chrome()
#?設(shè)置瀏覽器全屏
browser.maximize_window()???
browser.get(r'https://www.baidu.com')??
time.sleep(2)
#?打開(kāi)淘寶頁(yè)面
browser.get(r'https://www.taobao.com')??
time.sleep(2)
#?后退到百度頁(yè)面
browser.back()??
time.sleep(2)
#?前進(jìn)的淘寶頁(yè)面
browser.forward()?
time.sleep(2)
#?關(guān)閉瀏覽器
browser.close()2. 獲取頁(yè)面基礎(chǔ)屬性
當(dāng)我們用selenium打開(kāi)某個(gè)頁(yè)面,有一些基礎(chǔ)屬性如網(wǎng)頁(yè)標(biāo)題、網(wǎng)址、瀏覽器名稱、頁(yè)面源碼等信息。
from?selenium?import?webdriver
browser?=?webdriver.Chrome()
browser.get(r'https://www.baidu.com')?
#?網(wǎng)頁(yè)標(biāo)題
print(browser.title)
#?當(dāng)前網(wǎng)址
print(browser.current_url)
#?瀏覽器名稱
print(browser.name)
#?網(wǎng)頁(yè)源碼
print(browser.page_source)
輸出如下:
百度一下,你就知道
https://www.baidu.com/
chrome
"Content-Type"?content="text/html;charset=utf-8">"X-UA-Compatible"?content="IE=edge,chrome=1">"always"?name="referrer">"theme-color"..."
需要注意的是,這里的頁(yè)面源碼我們就可以用正則表達(dá)式、Bs4、xpath以及pyquery等工具進(jìn)行解析提取想要的信息了。
3. 定位頁(yè)面元素
我們?cè)趯?shí)際使用瀏覽器的時(shí)候,很重要的操作有輸入文本、點(diǎn)擊確定等等。對(duì)此,Selenium提供了一系列的方法來(lái)方便我們實(shí)現(xiàn)以上操作。常說(shuō)的8種定位頁(yè)面元素的操作方式,我們一一演示一下!
我們以百度首頁(yè)的搜索框節(jié)點(diǎn)為例,搜索python

搜索框的html結(jié)構(gòu):
<input?id="kw"?name="wd"?class="s_ipt"?value=""?maxlength="255"?autocomplete="off">
3.1. id定位
find_element_by_id()根據(jù)id屬性獲取,這里id屬性是 kw
from?selenium?import?webdriver
import?time??
browser?=?webdriver.Chrome()
browser.get(r'https://www.baidu.com')??
time.sleep(2)
#?在搜索框輸入?python
browser.find_element_by_id('kw').send_keys('python')
time.sleep(2)
#?關(guān)閉瀏覽器
browser.close()

3.2. name定位
find_element_by_name()根據(jù)name屬性獲取,這里name屬性是 wd
from?selenium?import?webdriver
import?time??
browser?=?webdriver.Chrome()
browser.get(r'https://www.baidu.com')??
time.sleep(2)
#?在搜索框輸入?python
browser.find_element_by_name('wd').send_keys('python')
time.sleep(2)
#?關(guān)閉瀏覽器
browser.close()
3.3. class定位
find_element_by_class_name()根據(jù)class屬性獲取,這里class屬性是s_ipt
from?selenium?import?webdriver
import?time??
browser?=?webdriver.Chrome()
browser.get(r'https://www.baidu.com')??
time.sleep(2)
#?在搜索框輸入?python
browser.find_element_by_class_name('s_ipt').send_keys('python')
time.sleep(2)
#?關(guān)閉瀏覽器
browser.close()
3.4. tag定位
我們知道HTML是通過(guò)tag來(lái)定義功能的,比如input是輸入,table是表格等等。每個(gè)元素其實(shí)就是一個(gè)tag,一個(gè)tag往往用來(lái)定義一類功能,我們查看百度首頁(yè)的html代碼,可以看到有很多同類tag,所以其實(shí)很難通過(guò)tag去區(qū)分不同的元素。
find_element_by_tag_name()
from?selenium?import?webdriver
import?time??
browser?=?webdriver.Chrome()
browser.get(r'https://www.baidu.com')??
time.sleep(2)
#?在搜索框輸入?python
browser.find_element_by_tag_name('input').send_keys('python')
time.sleep(2)
#?關(guān)閉瀏覽器
browser.close()
由于存在多個(gè)input,以上代碼會(huì)報(bào)錯(cuò)。
3.5. link定位
這種方法顧名思義就是用來(lái)定位文本鏈接的,比如百度首頁(yè)上方的分類模塊鏈接。
find_element_by_link_text()

以新聞為例
from?selenium?import?webdriver
import?time??
browser?=?webdriver.Chrome()
browser.get(r'https://www.baidu.com')??
time.sleep(2)
#?點(diǎn)擊新聞?鏈接
browser.find_element_by_link_text('新聞').click()
time.sleep(2)
#?關(guān)閉瀏覽器全部頁(yè)面
browser.quit()
3.6. partial定位
有時(shí)候一個(gè)超鏈接的文本很長(zhǎng),我們?nèi)绻枯斎耄嚷闊诛@得代碼很不美觀,這時(shí)候我們就可以只截取一部分字符串,用這種方法模糊匹配了。
find_element_by_partial_link_text()
from?selenium?import?webdriver
import?time??
browser?=?webdriver.Chrome()
browser.get(r'https://www.baidu.com')??
time.sleep(2)
#?點(diǎn)擊新聞?鏈接
browser.find_element_by_partial_link_text('聞').click()
time.sleep(2)
#?關(guān)閉瀏覽器全部頁(yè)面
browser.quit()
3.7. xpath定位
前面介紹的幾種定位方法都是在理想狀態(tài)下,有一定使用范圍的,那就是:在當(dāng)前頁(yè)面中,每個(gè)元素都有一個(gè)唯一的id或name或class或超鏈接文本的屬性,那么我們就可以通過(guò)這個(gè)唯一的屬性值來(lái)定位他們。
但是在實(shí)際工作中并非有這么美好,那么這個(gè)時(shí)候我們就只能通過(guò)xpath或者css來(lái)定位了。
find_element_by_xpath()
from?selenium?import?webdriver
import?time??
browser?=?webdriver.Chrome()
browser.get(r'https://www.baidu.com')??
time.sleep(2)
#?在搜索框輸入?python
browser.find_element_by_xpath("http://*[@id='kw']").send_keys('python')
time.sleep(2)
#?關(guān)閉瀏覽器
browser.close()
3.8. css定位
這種方法相對(duì)xpath要簡(jiǎn)潔些,定位速度也要快些。
find_element_by_css_selector()
from?selenium?import?webdriver
import?time??
browser?=?webdriver.Chrome()
browser.get(r'https://www.baidu.com')??
time.sleep(2)
#?在搜索框輸入?python
browser.find_element_by_css_selector('#kw').send_keys('python')
time.sleep(2)
#?關(guān)閉瀏覽器
browser.close()
3.9. find_element的By定位
除了上述的8種定位方法,Selenium還提供了一個(gè)通用的方法find_element(),這個(gè)方法有兩個(gè)參數(shù):定位方式和定位值。
#?使用前先導(dǎo)入By類
from?selenium.webdriver.common.by?import?By
以上的操作可以等同于以下:
browser.find_element(By.ID,'kw')
browser.find_element(By.NAME,'wd')
browser.find_element(By.CLASS_NAME,'s_ipt')
browser.find_element(By.TAG_NAME,'input')
browser.find_element(By.LINK_TEXT,'新聞')
browser.find_element(By.PARTIAL_LINK_TEXT,'聞')
browser.find_element(By.XPATH,'//*[@id="kw"]')
browser.find_element(By.CSS_SELECTOR,'#kw')
3.10. 多個(gè)元素
如果定位的目標(biāo)元素在網(wǎng)頁(yè)中不止一個(gè),那么則需要用到find_elements,得到的結(jié)果會(huì)是列表形式。簡(jiǎn)單來(lái)說(shuō),就是element后面多了復(fù)數(shù)標(biāo)識(shí)s,其他操作一致。
4. 獲取頁(yè)面元素屬性
既然我們有很多方式來(lái)定位頁(yè)面的元素,那么接下來(lái)就可以考慮獲取以下元素的屬性了,尤其是用Selenium進(jìn)行網(wǎng)絡(luò)爬蟲(chóng)的時(shí)候。
4.1. get_attribute獲取屬性
以百度首頁(yè)的logo為例,獲取logo相關(guān)屬性

<img?hidefocus="true"?id="s_lg_img"?class="index-logo-src"?src="http://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png"?width="270"?height="129"?onerror="this.src='//www.baidu.com/img/flexible/logo/pc/index.png';this.onerror=null;"?usemap="#mp">
獲取logo的圖片地址
from?selenium?import?webdriver
import?time??
browser?=?webdriver.Chrome()
browser.get(r'https://www.baidu.com')??
logo?=?browser.find_element_by_class_name('index-logo-src')
print(logo)
print(logo.get_attribute('src'))
#?關(guān)閉瀏覽器
browser.close()
輸出:
https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png
4.2. 獲取文本
以熱榜為例,獲取熱榜文本和鏈接

class="title-content?tag-width?c-link?c-font-medium?c-line-clamp1"?href="https://www.baidu.com/s?cl=3&tn=baidutop10&fr=top1000&wd=%E5%90%84%E5%9C%B0%E8%B4%AF%E5%BD%BB%E5%8D%81%E4%B9%9D%E5%B1%8A%E5%85%AD%E4%B8%AD%E5%85%A8%E4%BC%9A%E7%B2%BE%E7%A5%9E%E7%BA%AA%E5%AE%9E&rsv_idx=2&rsv_dl=fyb_n_homepage&sa=fyb_n_homepage&hisfilter=1"?target="_blank">">1">各地貫徹十九屆六中全會(huì)精神紀(jì)實(shí)
獲取熱榜的文本,用的是text屬性,直接調(diào)用即可
from?selenium?import?webdriver
import?time??
browser?=?webdriver.Chrome()
browser.get(r'https://www.baidu.com')??
logo?=?browser.find_element_by_css_selector('#hotsearch-content-wrapper?>?li:nth-child(1)?>?a')
print(logo.text)
print(logo.get_attribute('href'))
#?關(guān)閉瀏覽器
browser.close()
輸出:
1各地貫徹十九屆六中全會(huì)精神紀(jì)實(shí)
https://www.baidu.com/s?cl=3&tn=baidutop10&fr=top1000&wd=%E5%90%84%E5%9C%B0%E8%B4%AF%E5%BD%BB%E5%8D%81%E4%B9%9D%E5%B1%8A%E5%85%AD%E4%B8%AD%E5%85%A8%E4%BC%9A%E7%B2%BE%E7%A5%9E%E7%BA%AA%E5%AE%9E&rsv_idx=2&rsv_dl=fyb_n_homepage&sa=fyb_n_homepage&hisfilter=1
4.3. 獲取其他屬性
除了屬性和文本值外,還有id、位置、標(biāo)簽名和大小等屬性。
from?selenium?import?webdriver
import?time??
browser?=?webdriver.Chrome()
browser.get(r'https://www.baidu.com')??
logo?=?browser.find_element_by_class_name('index-logo-src')
print(logo.id)
print(logo.location)
print(logo.tag_name)
print(logo.size)
#?關(guān)閉瀏覽器
browser.close()
輸出:
6af39c9b-70e8-4033-8a74-7201ae09d540
{'x': 490, 'y': 46}
img
{'height': 129, 'width': 270}5. 頁(yè)面交互操作
頁(yè)面交互就是在瀏覽器的各種操作,比如上面演示過(guò)的輸入文本、點(diǎn)擊鏈接等等,還有像清除文本、回車確認(rèn)、單選框與多選框選中等。
5.1. 輸入文本
其實(shí),在之前的小節(jié)中我們有用過(guò)此操作。
send_keys()
from?selenium?import?webdriver
import?time??
browser?=?webdriver.Chrome()
browser.get(r'https://www.baidu.com')??
time.sleep(2)
#?定位搜索框
input?=?browser.find_element_by_class_name('s_ipt')
#?輸入python
input.send_keys('python')
time.sleep(2)
#?關(guān)閉瀏覽器
browser.close()
5.2. 點(diǎn)擊
同樣,我們也用過(guò)這個(gè)點(diǎn)擊操作。
click()
from?selenium?import?webdriver
import?time??
browser?=?webdriver.Chrome()
browser.get(r'https://www.baidu.com')??
time.sleep(2)
#?選中新聞按鈕
click?=?browser.find_element_by_link_text('新聞')
#?點(diǎn)擊之
click.click()
time.sleep(2)
#?關(guān)閉瀏覽器全部頁(yè)面
browser.quit()
5.3. 清除文本
既然有輸入,這里也就有清除文本啦。
clear()
from?selenium?import?webdriver
import?time??
browser?=?webdriver.Chrome()
browser.get(r'https://www.baidu.com')??
time.sleep(2)
#?定位搜索框
input?=?browser.find_element_by_class_name('s_ipt')
#?輸入python
input.send_keys('python')
time.sleep(2)
#?清除python
input.clear()
time.sleep(2)
#?關(guān)閉瀏覽器
browser.close()
5.4. 回車確認(rèn)
比如,在搜索框輸入文本python,然后回車就出查詢操作結(jié)果的情況。
submit()
from?selenium?import?webdriver
import?time??
browser?=?webdriver.Chrome()
browser.get(r'https://www.baidu.com')??
time.sleep(2)
#?定位搜索框
input?=?browser.find_element_by_class_name('s_ipt')
#?輸入python
input.send_keys('python')
time.sleep(2)
#?回車查詢
input.submit()
time.sleep(5)
#?關(guān)閉瀏覽器
browser.close()
5.5. 單選
單選比較好操作,先定位需要單選的某個(gè)元素,然后點(diǎn)擊一下即可。
5.6. 多選
多選好像也比較容易,依次定位需要選擇的元素,點(diǎn)擊即可。
5.7. 下拉框
下拉框的操作相對(duì)復(fù)雜一些,需要用到Select模塊。
先導(dǎo)入該類
from?selenium.webdriver.support.select?import?Select
在select模塊中有以下定位方法
'''1、三種選擇某一選項(xiàng)項(xiàng)的方法'''
select_by_index()???????????#?通過(guò)索引定位;注意:index索引是從“0”開(kāi)始。
select_by_value()???????????#?通過(guò)value值定位,value標(biāo)簽的屬性值。
select_by_visible_text()????#?通過(guò)文本值定位,即顯示在下拉框的值。
'''2、三種返回options信息的方法'''
options?????????????????????#?返回select元素所有的options
all_selected_options????????#?返回select元素中所有已選中的選項(xiàng)
first_selected_options??????#?返回select元素中選中的第一個(gè)選項(xiàng)??????????????????
'''3、四種取消選中項(xiàng)的方法'''
deselect_all????????????????#?取消全部的已選擇項(xiàng)
deselect_by_index???????????#?取消已選中的索引項(xiàng)
deselect_by_value???????????#?取消已選中的value值
deselect_by_visible_text????#?取消已選中的文本值
我們來(lái)進(jìn)行演示一波,由于暫時(shí)沒(méi)找到合適的網(wǎng)頁(yè),我這邊寫(xiě)了一個(gè)簡(jiǎn)單的網(wǎng)頁(yè)本地測(cè)試(文件存為 帥哥.html)
<html>
<body>
<form>
<select?name="帥哥">
<option?value="才哥">才哥option>
<option?value="小明"?selected="">小明option>
<option?value="小華">小華option>
<option?value="草兒">小草option>
select>
form>
body>
html>
然后,再演示下拉框的不同選擇的方式
from?selenium?import?webdriver
from?selenium.webdriver.support.select?import?Select
import?time
url?=?'file:///C:/Users/Gdc/Desktop/帥哥.html'
browser?=?webdriver.Chrome()
browser.get(url)
time.sleep(2)
#?根據(jù)索引選擇
Select(browser.find_element_by_name("帥哥")).select_by_index("2")
time.sleep(2)
#?根據(jù)value值選擇
Select(browser.find_element_by_name("帥哥")).select_by_value("草兒")
time.sleep(2)
#?根據(jù)文本值選擇
Select(browser.find_element_by_name("帥哥")).select_by_visible_text("才哥")
time.sleep(2)
#?關(guān)閉瀏覽器
browser.close()

6. 多窗口切換
比如同一個(gè)頁(yè)面的不同子頁(yè)面的節(jié)點(diǎn)元素獲取操作,不同選項(xiàng)卡之間的切換以及不同瀏覽器窗口之間的切換操作等等。
6.1. Frame切換
Selenium打開(kāi)一個(gè)頁(yè)面之后,默認(rèn)是在父頁(yè)面進(jìn)行操作,此時(shí)如果這個(gè)頁(yè)面還有子頁(yè)面,想要獲取子頁(yè)面的節(jié)點(diǎn)元素信息則需要切換到子頁(yè)面進(jìn)行擦走,這時(shí)候switch_to.frame()就來(lái)了。如果想回到父頁(yè)面,用switch_to.parent_frame()即可。
6.2. 選項(xiàng)卡切換
我們?cè)谠L問(wèn)網(wǎng)頁(yè)的時(shí)候會(huì)打開(kāi)很多個(gè)頁(yè)面,在Selenium中提供了一些方法方便我們對(duì)這些頁(yè)面進(jìn)行操作。
current_window_handle:獲取當(dāng)前窗口的句柄。
window_handles:返回當(dāng)前瀏覽器的所有窗口的句柄。
switch_to_window():用于切換到對(duì)應(yīng)的窗口。
from?selenium?import?webdriver
import?time
browser?=?webdriver.Chrome()
#?打開(kāi)百度
browser.get('http://www.baidu.com')
#?新建一個(gè)選項(xiàng)卡
browser.execute_script('window.open()')
print(browser.window_handles)
#?跳轉(zhuǎn)到第二個(gè)選項(xiàng)卡并打開(kāi)知乎
browser.switch_to.window(browser.window_handles[1])
browser.get('http://www.zhihu.com')
#?回到第一個(gè)選項(xiàng)卡并打開(kāi)淘寶(原來(lái)的百度頁(yè)面改為了淘寶)
time.sleep(2)
browser.switch_to.window(browser.window_handles[0])
browser.get('http://www.taobao.com')7. 模擬鼠標(biāo)操作
既然是模擬瀏覽器操作,自然也就需要能模擬鼠標(biāo)的一些操作了,這里需要導(dǎo)入ActionChains 類。
from?selenium.webdriver.common.action_chains?import?ActionChains
7.1. 左鍵
這個(gè)其實(shí)就是頁(yè)面交互操作中的點(diǎn)擊click()操作。
7.2. 右鍵
context_click()
from?selenium.webdriver.common.action_chains?import?ActionChains
from?selenium?import?webdriver
import?time??
browser?=?webdriver.Chrome()
browser.get(r'https://www.baidu.com')??
time.sleep(2)
#?定位到要右擊的元素,這里選的新聞鏈接
right_click?=?browser.find_element_by_link_text('新聞')
#?執(zhí)行鼠標(biāo)右鍵操作
ActionChains(browser).context_click(right_click).perform()
time.sleep(2)
#?關(guān)閉瀏覽器
browser.close()
在上述操作中
ActionChains(browser):調(diào)用ActionChains()類,并將瀏覽器驅(qū)動(dòng)browser作為參數(shù)傳入
context_click(right_click):模擬鼠標(biāo)雙擊,需要傳入指定元素定位作為參數(shù)
perform():執(zhí)行ActionChains()中儲(chǔ)存的所有操作,可以看做是執(zhí)行之前一系列的操作
7.3. 雙擊
double_click()
from?selenium.webdriver.common.action_chains?import?ActionChains
from?selenium?import?webdriver
import?time??
browser?=?webdriver.Chrome()
browser.get(r'https://www.baidu.com')??
time.sleep(2)
#?定位到要雙擊的元素
double_click?=?browser.find_element_by_css_selector('#bottom_layer?>?div?>?p:nth-child(8)?>?span')
#?雙擊
ActionChains(browser).double_click(double_click).perform()
time.sleep(15)
#?關(guān)閉瀏覽器
browser.close()

7.4. 拖拽
drag_and_drop(source,target)拖拽操作嘛,開(kāi)始位置和結(jié)束位置需要被指定,這個(gè)常用于滑塊類驗(yàn)證碼的操作之類。
我們以菜鳥(niǎo)教程的一個(gè)案例來(lái)進(jìn)行演示
https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable
from?selenium.webdriver.common.action_chains?import?ActionChains
from?selenium?import?webdriver
import?time??
browser?=?webdriver.Chrome()
url?=?'https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable'
browser.get(url)??
time.sleep(2)
browser.switch_to.frame('iframeResult')
#?開(kāi)始位置
source?=?browser.find_element_by_css_selector("#draggable")
#?結(jié)束位置
target?=?browser.find_element_by_css_selector("#droppable")
#?執(zhí)行元素的拖放操作
actions?=?ActionChains(browser)
actions.drag_and_drop(source,?target)
actions.perform()
#?拖拽
time.sleep(15)
#?關(guān)閉瀏覽器
browser.close()

7.5. 懸停
move_to_element()
from?selenium.webdriver.common.action_chains?import?ActionChains
from?selenium?import?webdriver
import?time??
browser?=?webdriver.Chrome()
url?=?'https://www.baidu.com'
browser.get(url)??
time.sleep(2)
#?定位懸停的位置
move?=?browser.find_element_by_css_selector("#form?>?span.bg.s_ipt_wr.new-pmd.quickdelete-wrap?>?span.soutu-btn")
#?懸停操作
ActionChains(browser).move_to_element(move).perform()
time.sleep(5)
#?關(guān)閉瀏覽器
browser.close()

8. 模擬鍵盤(pán)操作
selenium中的Keys()類提供了大部分的鍵盤(pán)操作方法,通過(guò)send_keys()方法來(lái)模擬鍵盤(pán)上的按鍵。
引入Keys類
from?selenium.webdriver.common.keys?import?Keys
常見(jiàn)的鍵盤(pán)操作
send_keys(Keys.BACK_SPACE):刪除鍵(BackSpace)
send_keys(Keys.SPACE):空格鍵(Space)
send_keys(Keys.TAB):制表鍵(TAB)
send_keys(Keys.ESCAPE):回退鍵(ESCAPE)
send_keys(Keys.ENTER):回車鍵(ENTER)
send_keys(Keys.CONTRL,'a'):全選(Ctrl+A)
send_keys(Keys.CONTRL,'c'):復(fù)制(Ctrl+C)
send_keys(Keys.CONTRL,'x'):剪切(Ctrl+X)
send_keys(Keys.CONTRL,'v'):粘貼(Ctrl+V)
send_keys(Keys.F1):鍵盤(pán)F1.....
send_keys(Keys.F12):鍵盤(pán)F12
實(shí)例操作演示:
定位需要操作的元素,然后操作即可!
from?selenium.webdriver.common.keys?import?Keys
from?selenium?import?webdriver
import?time
browser?=?webdriver.Chrome()
url?=?'https://www.baidu.com'
browser.get(url)??
time.sleep(2)
#?定位搜索框
input?=?browser.find_element_by_class_name('s_ipt')
#?輸入python
input.send_keys('python')
time.sleep(2)
#?回車
input.send_keys(Keys.ENTER)
time.sleep(5)
#?關(guān)閉瀏覽器
browser.close()9. 延時(shí)等待
如果遇到使用ajax加載的網(wǎng)頁(yè),頁(yè)面元素可能不是同時(shí)加載出來(lái)的,這個(gè)時(shí)候嘗試在get方法執(zhí)行完成時(shí)獲取網(wǎng)頁(yè)源代碼可能并非瀏覽器完全加載完成的頁(yè)面。所以,這種情況下需要設(shè)置延時(shí)等待一定時(shí)間,確保全部節(jié)點(diǎn)都加載出來(lái)。
三種方式可以來(lái)玩玩:強(qiáng)制等待、隱式等待和顯式等待
9.1. 強(qiáng)制等待
就很簡(jiǎn)單了,直接time.sleep(n)強(qiáng)制等待n秒,在執(zhí)行get方法之后執(zhí)行。
9.2. 隱式等待
implicitly_wait()設(shè)置等待時(shí)間,如果到時(shí)間有元素節(jié)點(diǎn)沒(méi)有加載出來(lái),就會(huì)拋出異常。
from?selenium?import?webdriver
browser?=?webdriver.Chrome()
#?隱式等待,等待時(shí)間10秒
browser.implicitly_wait(10)??
browser.get('https://www.baidu.com')
print(browser.current_url)
print(browser.title)
#?關(guān)閉瀏覽器
browser.close()
9.3. 顯式等待
設(shè)置一個(gè)等待時(shí)間和一個(gè)條件,在規(guī)定時(shí)間內(nèi),每隔一段時(shí)間查看下條件是否成立,如果成立那么程序就繼續(xù)執(zhí)行,否則就拋出一個(gè)超時(shí)異常。
from?selenium?import?webdriver
from?selenium.webdriver.support.wait?import?WebDriverWait
from?selenium.webdriver.support?import?expected_conditions?as?EC
from?selenium.webdriver.common.by?import?By
import?time
browser?=?webdriver.Chrome()
browser.get('https://www.baidu.com')
#?設(shè)置等待時(shí)間10s
wait?=?WebDriverWait(browser,?10)
#?設(shè)置判斷條件:等待id='kw'的元素加載完成
input?=?wait.until(EC.presence_of_element_located((By.ID,?'kw')))
#?在關(guān)鍵詞輸入:關(guān)鍵詞
input.send_keys('Python')
#?關(guān)閉瀏覽器
time.sleep(2)
browser.close()
WebDriverWait的參數(shù)說(shuō)明:
WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None)
driver: 瀏覽器驅(qū)動(dòng)
timeout: 超時(shí)時(shí)間,等待的最長(zhǎng)時(shí)間(同時(shí)要考慮隱性等待時(shí)間)
poll_frequency: 每次檢測(cè)的間隔時(shí)間,默認(rèn)是0.5秒
ignored_exceptions:超時(shí)后的異常信息,默認(rèn)情況下拋出NoSuchElementException異常
until(method,message='')
method: 在等待期間,每隔一段時(shí)間調(diào)用這個(gè)傳入的方法,直到返回值不是False
message: 如果超時(shí),拋出TimeoutException,將message傳入異常
until_not(method,message='')
until_not與until相反,until是當(dāng)某元素出現(xiàn)或什么條件成立則繼續(xù)執(zhí)行,until_not是當(dāng)某元素消失或什么條件不成立則繼續(xù)執(zhí)行,參數(shù)也相同。
其他等待條件
from?selenium.webdriver.support?import?expected_conditions?as?EC
#?判斷標(biāo)題是否和預(yù)期的一致
title_is
#?判斷標(biāo)題中是否包含預(yù)期的字符串
title_contains
#?判斷指定元素是否加載出來(lái)
presence_of_element_located
#?判斷所有元素是否加載完成
presence_of_all_elements_located
#?判斷某個(gè)元素是否可見(jiàn).?可見(jiàn)代表元素非隱藏,并且元素的寬和高都不等于0,傳入?yún)?shù)是元組類型的locator
visibility_of_element_located
#?判斷元素是否可見(jiàn),傳入?yún)?shù)是定位后的元素WebElement
visibility_of
#?判斷某個(gè)元素是否不可見(jiàn),或是否不存在于DOM樹(shù)
invisibility_of_element_located
#?判斷元素的?text?是否包含預(yù)期字符串
text_to_be_present_in_element
#?判斷元素的?value?是否包含預(yù)期字符串
text_to_be_present_in_element_value
#判斷frame是否可切入,可傳入locator元組或者直接傳入定位方式:id、name、index或WebElement
frame_to_be_available_and_switch_to_it
#判斷是否有alert出現(xiàn)
alert_is_present
#判斷元素是否可點(diǎn)擊
element_to_be_clickable
#?判斷元素是否被選中,一般用在下拉列表,傳入WebElement對(duì)象
element_to_be_selected
#?判斷元素是否被選中
element_located_to_be_selected
#?判斷元素的選中狀態(tài)是否和預(yù)期一致,傳入?yún)?shù):定位后的元素,相等返回True,否則返回False
element_selection_state_to_be
#?判斷元素的選中狀態(tài)是否和預(yù)期一致,傳入?yún)?shù):元素的定位,相等返回True,否則返回False
element_located_selection_state_to_be
#判斷一個(gè)元素是否仍在DOM中,傳入WebElement對(duì)象,可以判斷頁(yè)面是否刷新了
staleness_of10. 其他
補(bǔ)充一些
10.1. 運(yùn)行JavaScript
還有一些操作,比如下拉進(jìn)度條,模擬javaScript,使用execute_script方法來(lái)實(shí)現(xiàn)。
from?selenium?import?webdriver
browser?=?webdriver.Chrome()
#?知乎發(fā)現(xiàn)頁(yè)
browser.get('https://www.zhihu.com/explore')
browser.execute_script('window.scrollTo(0,?document.body.scrollHeight)')
browser.execute_script('alert("To?Bottom")')

10.2. Cookie
在selenium使用過(guò)程中,還可以很方便對(duì)Cookie進(jìn)行獲取、添加與刪除等操作。
from?selenium?import?webdriver
browser?=?webdriver.Chrome()
#?知乎發(fā)現(xiàn)頁(yè)
browser.get('https://www.zhihu.com/explore')
#?獲取cookie
print(f'Cookies的值:{browser.get_cookies()}')
#?添加cookie
browser.add_cookie({'name':'才哥',?'value':'帥哥'})
print(f'添加后Cookies的值:{browser.get_cookies()}')
#?刪除cookie
browser.delete_all_cookies()
print(f'刪除后Cookies的值:{browser.get_cookies()}')
輸出:
Cookies的值:[{'domain':?'.zhihu.com',?'httpOnly':?False,?'name':?'Hm_lpvt_98beee57fd2ef70ccdd5ca52b9740c49',?'path':?'/',?'secure':?False,?'value':?'1640537860'},?{'domain':?'.zhihu.com',?...]
添加后Cookies的值:[{'domain':?'www.zhihu.com',?'httpOnly':?False,?'name':?'才哥',?'path':?'/',?'secure':?True,?'value':?'帥哥'},?{'domain':?'.zhihu.com',?'httpOnly':?False,?'name':?'Hm_lpvt_98beee57fd2ef70ccdd5ca52b9740c49',?'path':?'/',?'secure':?False,?'value':?'1640537860'},?{'domain':?'.zhihu.com',...]
刪除后Cookies的值:[]
10.3. 反屏蔽
發(fā)現(xiàn)美團(tuán)直接給Selenium給屏蔽了,不知道怎么搞!!
以上就是本次全部?jī)?nèi)容,如果覺(jué)得有幫助,還請(qǐng)點(diǎn)贊+在看呀!
后續(xù)我們將演示Selenium在爬蟲(chóng)以及web自動(dòng)化方面的一些實(shí)戰(zhàn)案例,敬請(qǐng)期待!
--End--
如何找到我:
學(xué)習(xí)更多: 整理了我開(kāi)始分享學(xué)習(xí)筆記到現(xiàn)在超過(guò)250篇優(yōu)質(zhì)文章,涵蓋數(shù)據(jù)分析、爬蟲(chóng)、機(jī)器學(xué)習(xí)等方面,別再說(shuō)不知道該從哪開(kāi)始,實(shí)戰(zhàn)哪里找了
