2 萬字帶你瞭解 Selenium 全攻略

今天帶大家一起學 (復) 習模擬瀏覽器運行的庫Selenium,它是一個用於Web應用程序測試的工具。Selenium測試直接運行在瀏覽器中,就像真正的用戶在操作一樣。支持的瀏覽器包括IE(7, 8, 9, 10, 11),Mozilla FirefoxSafariGoogle ChromeOperaEdge等。

這裏我將以Chrome爲例進行Selenium功能的演示~

0. 準備工作

在開始後續功能演示之前,我們需要先安裝Chrome瀏覽器並配置好ChromeDriver,當然也需要安裝selenium庫!

0.1. 安裝 selenium 庫

pip install selenium

0.2. 安裝瀏覽器驅動

其實,有兩種方式安裝瀏覽器驅動:一種是常見的手動安裝,另一種則是利用第三方庫自動安裝。

以下前提:大家都已經安裝好了Chrome瀏覽器哈

手動安裝

先查看本地Chrome瀏覽器版本:(兩種方式均可)

再選擇對應版本號的驅動版本

下載地址:https://chromedriver.storage.googleapis.com/index.html

最後進行環境變量配置,也就是將對應的ChromeDriver的可執行文件chromedriver.exe文件拖到PythonScripts目錄下。

注:當然也可以不這樣做,但是在調用的時候指定chromedriver.exe絕對路徑亦可。

自動安裝

自動安裝需要用到第三方庫webdriver_manager,先安裝這個庫,然後調用對應的方法即可。

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)

# 關閉瀏覽器
browser.close()

在上述代碼中,ChromeDriverManager().install()方法就是自動安裝驅動的操作,它會自動獲取當前瀏覽器的版本並去下載對應的驅動到本地。

====== 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]

如果本地已經有該瀏覽器渠道,則會提示其已存在。

====== 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

搞定以上準備工作,我們就可以開始本文正式內容的學習啦~

1. 基本用法

這節我們就從初始化瀏覽器對象、訪問頁面、設置瀏覽器大小、刷新頁面和前進後退等基礎操作。

1.1. 初始化瀏覽器對象

在準備工作部分我們提到需要將瀏覽器渠道添加到環境變量或者指定絕對路徑,前者可以直接初始化後者則需要進行指定。

from selenium import webdriver

# 初始化瀏覽器爲chrome瀏覽器
browser = webdriver.Chrome()

# 指定絕對路徑的方式
path = r'C:\Users\Gdc\.wdm\drivers\chromedriver\win32\96.0.4664.45\chromedriver.exe'
browser = webdriver.Chrome(path)

# 關閉瀏覽器
browser.close()

初始化瀏覽器對象

可以看到以上是有界面的瀏覽器,我們還可以初始化瀏覽器爲無界面的瀏覽器

from selenium import webdriver

# 無界面的瀏覽器
option = webdriver.ChromeOptions()
option.add_argument("headless")
browser = webdriver.Chrome(options=option)

# 訪問百度首頁
browser.get(r'https://www.baidu.com/')
# 截圖預覽
browser.get_screenshot_as_file('截圖.png')

# 關閉瀏覽器
browser.close()

截圖

完成瀏覽器對象的初始化後並將其賦值給了browser對象,接下來我們就可以調用browser來執行各種方法模擬瀏覽器的操作了。

1.2. 訪問頁面

進行頁面訪問使用的是get方法,傳入參數爲待訪問頁面的URL地址即可。

from selenium import webdriver

# 初始化瀏覽器爲chrome瀏覽器
browser = webdriver.Chrome()

# 訪問百度首頁
browser.get(r'https://www.baidu.com/')

# 關閉瀏覽器
browser.close()

1.3. 設置瀏覽器大小

set_window_size()方法可以用來設置瀏覽器大小(就是分辨率),而maximize_window則是設置瀏覽器爲全屏!

from selenium import webdriver
import time  

browser = webdriver.Chrome()

# 設置瀏覽器大小:全屏
browser.maximize_window()   
browser.get(r'https://www.baidu.com')  
time.sleep(2)

# 設置分辨率 500*500
browser.set_window_size(500,500)  
time.sleep(2)

# 設置分辨率 1000*800
browser.set_window_size(1000,800) 
time.sleep(2)

# 關閉瀏覽器
browser.close()

這裏就不截圖了,大家自行演示看效果哈~

1.4. 刷新頁面

刷新頁面是我們在瀏覽器操作時很常用的操作,這裏refresh()方法可以用來進行瀏覽器頁面刷新。

from selenium import webdriver
import time  

browser = webdriver.Chrome()

# 設置瀏覽器全屏
browser.maximize_window()   
browser.get(r'https://www.baidu.com')  
time.sleep(2)

try:
    # 刷新頁面
    browser.refresh()  
    print('刷新頁面')
except Exception as e:
    print('刷新失敗')
   
# 關閉瀏覽器
browser.close()

大家也是自行演示看效果哈,同F5快捷鍵。

1.5. 前進後退

前進後退也是我們在使用瀏覽器時非常常見的操作,這裏forward()方法可以用來實現前進,back()可以用來實現後退。

from selenium import webdriver
import time  

browser = webdriver.Chrome()

# 設置瀏覽器全屏
browser.maximize_window()   
browser.get(r'https://www.baidu.com')  
time.sleep(2)

# 打開淘寶頁面
browser.get(r'https://www.taobao.com')  
time.sleep(2)

# 後退到百度頁面
browser.back()  
time.sleep(2)

# 前進的淘寶頁面
browser.forward() 
time.sleep(2)

# 關閉瀏覽器
browser.close()

2. 獲取頁面基礎屬性

當我們用selenium打開某個頁面,有一些基礎屬性如網頁標題、網址、瀏覽器名稱、頁面源碼等信息。

from selenium import webdriver

browser = webdriver.Chrome()
browser.get(r'https://www.baidu.com') 

# 網頁標題
print(browser.title)
# 當前網址
print(browser.current_url)
# 瀏覽器名稱
print(browser.name)
# 網頁源碼
print(browser.page_source)

輸出如下:

百度一下,你就知道
https://www.baidu.com/
chrome
<html><head><script async="" src="https://passport.baidu.com/passApi/js/wrapper.js?cdnversion=1640515789507&_=1640515789298"></script><meta http-equiv="Content-Type" content="text/html;charset=utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta content="always"

需要注意的是,這裏的頁面源碼我們就可以用正則表達式Bs4xpath以及pyquery等工具進行解析提取想要的信息了。

3. 定位頁面元素

我們在實際使用瀏覽器的時候,很重要的操作有輸入文本、點擊確定等等。對此,Selenium提供了一系列的方法來方便我們實現以上操作。常說的8種定位頁面元素的操作方式,我們一一演示一下!

我們以百度首頁的搜索框節點爲例,搜索 python

搜索框

搜索框的html結構:

<input id="kw" >

3.1. id 定位

find_element_by_id()根據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)

# 關閉瀏覽器
browser.close()

3.2. name 定位

find_element_by_name()根據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)

# 關閉瀏覽器
browser.close()

3.3. class 定位

find_element_by_class_name()根據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)

# 關閉瀏覽器
browser.close()

3.4. tag 定位

我們知道HTML是通過tag來定義功能的,比如input是輸入,table是表格等等。每個元素其實就是一個tag,一個tag往往用來定義一類功能,我們查看百度首頁的html代碼,可以看到有很多同類tag,所以其實很難通過tag去區分不同的元素。

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)

# 關閉瀏覽器
browser.close()

由於存在多個input,以上代碼會報錯。

這種方法顧名思義就是用來定位文本鏈接的,比如百度首頁上方的分類模塊鏈接。

find_element_by_link_text()

以新聞爲例

from selenium import webdriver
import time  

browser = webdriver.Chrome()

browser.get(r'https://www.baidu.com')  
time.sleep(2)

# 點擊新聞 鏈接
browser.find_element_by_link_text('新聞').click()
time.sleep(2)

# 關閉瀏覽器全部頁面
browser.quit()

3.6. partial 定位

有時候一個超鏈接的文本很長,我們如果全部輸入,既麻煩,又顯得代碼很不美觀,這時候我們就可以只截取一部分字符串,用這種方法模糊匹配了。

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)

# 點擊新聞 鏈接
browser.find_element_by_partial_link_text('聞').click()
time.sleep(2)

# 關閉瀏覽器全部頁面
browser.quit()

3.7. xpath 定位

前面介紹的幾種定位方法都是在理想狀態下,有一定使用範圍的,那就是:在當前頁面中,每個元素都有一個唯一idnameclass超鏈接文本的屬性,那麼我們就可以通過這個唯一的屬性值來定位他們。

但是在實際工作中並非有這麼美好,那麼這個時候我們就只能通過xpath或者css來定位了。

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("//*[@id='kw']").send_keys('python')
time.sleep(2)

# 關閉瀏覽器
browser.close()

3.8. css 定位

這種方法相對xpath要簡潔些,定位速度也要快些。

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)

# 關閉瀏覽器
browser.close()

3.9. find_element 的 By 定位

除了上述的8種定位方法,Selenium還提供了一個通用的方法find_element(),這個方法有兩個參數:定位方式和定位值。

# 使用前先導入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. 多個元素

如果定位的目標元素在網頁中不止一個,那麼則需要用到find_elements,得到的結果會是列表形式。簡單來說,就是element後面多了複數標識s,其他操作一致。

4. 獲取頁面元素屬性

既然我們有很多方式來定位頁面的元素,那麼接下來就可以考慮獲取以下元素的屬性了,尤其是用Selenium進行網絡爬蟲的時候。

4.1. get_attribute 獲取屬性

以百度首頁的 logo 爲例,獲取 logo 相關屬性

<img hidefocus="true" id="s_lg_img" class="index-logo-src" src="//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'))

# 關閉瀏覽器
browser.close()

輸出:

<selenium.webdriver.remote.webelement.WebElement (session="e95b18c43a330745af019e0041f0a8a4", element="7dad5fc0-610b-45b6-b543-9e725ee6cc5d")>
https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png

4.2. 獲取文本

以熱榜爲例,獲取熱榜文本和鏈接

<a 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"><span class="title-content-index c-index-single c-index-single-hot1">1</span><span class="title-content-title">各地貫徹十九屆六中全會精神紀實</span></a>

獲取熱榜的文本,用的是text屬性,直接調用即可

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'))

# 關閉瀏覽器
browser.close()

輸出:

1各地貫徹十九屆六中全會精神紀實
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、位置、標籤名和大小等屬性。

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)

# 關閉瀏覽器
browser.close()

輸出:

6af39c9b-70e8-4033-8a74-7201ae09d540
{'x': 490, 'y': 46}
img
{'height': 129, 'width': 270}

5. 頁面交互操作

頁面交互就是在瀏覽器的各種操作,比如上面演示過的輸入文本、點擊鏈接等等,還有像清除文本、回車確認、單選框與多選框選中等。

5.1. 輸入文本

其實,在之前的小節中我們有用過此操作。

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)

# 關閉瀏覽器
browser.close()

5.2. 點擊

同樣,我們也用過這個點擊操作。

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('新聞')
# 點擊之
click.click()
time.sleep(2)

# 關閉瀏覽器全部頁面
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)

# 關閉瀏覽器
browser.close()

5.4. 回車確認

比如,在搜索框輸入文本python,然後回車就出查詢操作結果的情況。

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)

# 關閉瀏覽器
browser.close()

5.5. 單選

單選比較好操作,先定位需要單選的某個元素,然後點擊一下即可。

5.6. 多選

多選好像也比較容易,依次定位需要選擇的元素,點擊即可。

5.7. 下拉框

下拉框的操作相對複雜一些,需要用到Select模塊。

先導入該類

from selenium.webdriver.support.select import Select

select模塊中有以下定位方法

'''1、三種選擇某一選項項的方法'''

select_by_index()           # 通過索引定位;注意:index索引是從“0”開始。
select_by_value()           # 通過value值定位,value標籤的屬性值。
select_by_visible_text()    # 通過文本值定位,即顯示在下拉框的值。

'''2、三種返回options信息的方法'''

options                     # 返回select元素所有的options
all_selected_options        # 返回select元素中所有已選中的選項
first_selected_options      # 返回select元素中選中的第一個選項                  


'''3、四種取消選中項的方法'''

deselect_all                # 取消全部的已選擇項
deselect_by_index           # 取消已選中的索引項
deselect_by_value           # 取消已選中的value值
deselect_by_visible_text    # 取消已選中的文本值

我們來進行演示一波,由於暫時沒找到合適的網頁,我這邊寫了一個簡單的網頁本地測試(文件存爲 帥哥. html)

<html>

<body>

<form>
<select >
<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)

# 根據索引選擇
Select(browser.find_element_by_name("帥哥")).select_by_index("2")
time.sleep(2)
# 根據value值選擇
Select(browser.find_element_by_name("帥哥")).select_by_value("草兒")
time.sleep(2)
# 根據文本值選擇
Select(browser.find_element_by_name("帥哥")).select_by_visible_text("才哥")
time.sleep(2)

# 關閉瀏覽器
browser.close()

下拉框

6. 多窗口切換

比如同一個頁面的不同子頁面的節點元素獲取操作,不同選項卡之間的切換以及不同瀏覽器窗口之間的切換操作等等。

6.1. Frame 切換

Selenium打開一個頁面之後,默認是在父頁面進行操作,此時如果這個頁面還有子頁面,想要獲取子頁面的節點元素信息則需要切換到子頁面進行擦走,這時候switch_to.frame()就來了。如果想回到父頁面,用switch_to.parent_frame()即可。

6.2. 選項卡切換

我們在訪問網頁的時候會打開很多個頁面,在Selenium中提供了一些方法方便我們對這些頁面進行操作。

current_window_handle:獲取當前窗口的句柄。

window_handles:返回當前瀏覽器的所有窗口的句柄。

switch_to_window():用於切換到對應的窗口。

from selenium import webdriver
import time

browser = webdriver.Chrome()

# 打開百度
browser.get('http://www.baidu.com')
# 新建一個選項卡
browser.execute_script('window.open()')
print(browser.window_handles)
# 跳轉到第二個選項卡並打開知乎
browser.switch_to.window(browser.window_handles[1])
browser.get('http://www.zhihu.com')
# 回到第一個選項卡並打開淘寶(原來的百度頁面改爲了淘寶)
time.sleep(2)
browser.switch_to.window(browser.window_handles[0])
browser.get('http://www.taobao.com')

7. 模擬鼠標操作

既然是模擬瀏覽器操作,自然也就需要能模擬鼠標的一些操作了,這裏需要導入ActionChains 類。

from selenium.webdriver.common.action_chains import ActionChains

7.1. 左鍵

這個其實就是頁面交互操作中的點擊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('新聞')

# 執行鼠標右鍵操作
ActionChains(browser).context_click(right_click).perform()
time.sleep(2)

# 關閉瀏覽器
browser.close()

在上述操作中

ActionChains(browser):調用ActionChains()類,並將瀏覽器驅動browser作爲參數傳入

context_click(right_click):模擬鼠標雙擊,需要傳入指定元素定位作爲參數

perform():執行ActionChains()中儲存的所有操作,可以看做是執行之前一系列的操作

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)

# 關閉瀏覽器
browser.close()

7.4. 拖拽

drag_and_drop(source,target)拖拽操作嘛,開始位置和結束位置需要被指定,這個常用於滑塊類驗證碼的操作之類。

我們以菜鳥教程的一個案例來進行演示

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')

# 開始位置
source = browser.find_element_by_css_selector("#draggable")

# 結束位置
target = browser.find_element_by_css_selector("#droppable")

# 執行元素的拖放操作
actions = ActionChains(browser)
actions.drag_and_drop(source, target)
actions.perform()
# 拖拽
time.sleep(15)

# 關閉瀏覽器
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)

# 關閉瀏覽器
browser.close()

懸停效果

8. 模擬鍵盤操作

selenium中的Keys()類提供了大部分的鍵盤操作方法,通過send_keys()方法來模擬鍵盤上的按鍵。

引入Keys

from selenium.webdriver.common.keys import Keys

常見的鍵盤操作

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'):複製 (Ctrl+C)

send_keys(Keys.CONTRL,'x'):剪切 (Ctrl+X)

send_keys(Keys.CONTRL,'v'):粘貼 (Ctrl+V)

send_keys(Keys.F1):鍵盤 F1

.....

send_keys(Keys.F12):鍵盤 F12

實例操作演示:

定位需要操作的元素,然後操作即可!

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)

# 關閉瀏覽器
browser.close()

9. 延時等待

如果遇到使用ajax加載的網頁,頁面元素可能不是同時加載出來的,這個時候嘗試在get方法執行完成時獲取網頁源代碼可能並非瀏覽器完全加載完成的頁面。所以,這種情況下需要設置延時等待一定時間,確保全部節點都加載出來。

三種方式可以來玩玩:強制等待、隱式等待和顯式等待

9.1. 強制等待

就很簡單了,直接time.sleep(n)強制等待 n 秒,在執行get方法之後執行。

9.2. 隱式等待

implicitly_wait()設置等待時間,如果到時間有元素節點沒有加載出來,就會拋出異常。

from selenium import webdriver

browser = webdriver.Chrome()

# 隱式等待,等待時間10秒
browser.implicitly_wait(10)  

browser.get('https://www.baidu.com')
print(browser.current_url)
print(browser.title)

# 關閉瀏覽器
browser.close()

9.3. 顯式等待

設置一個等待時間和一個條件,在規定時間內,每隔一段時間查看下條件是否成立,如果成立那麼程序就繼續執行,否則就拋出一個超時異常。

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')
# 設置等待時間10s
wait = WebDriverWait(browser, 10)
# 設置判斷條件:等待id='kw'的元素加載完成
input = wait.until(EC.presence_of_element_located((By.ID, 'kw')))
# 在關鍵詞輸入:關鍵詞
input.send_keys('Python')

# 關閉瀏覽器
time.sleep(2)
browser.close()

WebDriverWait 的參數說明

WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None)

driver: 瀏覽器驅動

timeout: 超時時間,等待的最長時間(同時要考慮隱性等待時間)

poll_frequency: 每次檢測的間隔時間,默認是 0.5 秒

ignored_exceptions: 超時後的異常信息,默認情況下拋出NoSuchElementException異常

until(method,message='')

method: 在等待期間,每隔一段時間調用這個傳入的方法,直到返回值不是 False

message: 如果超時,拋出TimeoutException,將message傳入異常

until_not(method,message='')

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

其他等待條件

from selenium.webdriver.support import expected_conditions as EC

# 判斷標題是否和預期的一致
title_is
# 判斷標題中是否包含預期的字符串
title_contains

# 判斷指定元素是否加載出來
presence_of_element_located
# 判斷所有元素是否加載完成
presence_of_all_elements_located

# 判斷某個元素是否可見. 可見代表元素非隱藏,並且元素的寬和高都不等於0,傳入參數是元組類型的locator
visibility_of_element_located
# 判斷元素是否可見,傳入參數是定位後的元素WebElement
visibility_of
# 判斷某個元素是否不可見,或是否不存在於DOM樹
invisibility_of_element_located

# 判斷元素的 text 是否包含預期字符串
text_to_be_present_in_element
# 判斷元素的 value 是否包含預期字符串
text_to_be_present_in_element_value

#判斷frame是否可切入,可傳入locator元組或者直接傳入定位方式:id、name、index或WebElement
frame_to_be_available_and_switch_to_it

#判斷是否有alert出現
alert_is_present

#判斷元素是否可點擊
element_to_be_clickable

# 判斷元素是否被選中,一般用在下拉列表,傳入WebElement對象
element_to_be_selected
# 判斷元素是否被選中
element_located_to_be_selected
# 判斷元素的選中狀態是否和預期一致,傳入參數:定位後的元素,相等返回True,否則返回False
element_selection_state_to_be
# 判斷元素的選中狀態是否和預期一致,傳入參數:元素的定位,相等返回True,否則返回False
element_located_selection_state_to_be

#判斷一個元素是否仍在DOM中,傳入WebElement對象,可以判斷頁面是否刷新了
staleness_of

10. 其他

補充一些

10.1. 運行 JavaScript

還有一些操作,比如下拉進度條,模擬javaScript,使用execute_script方法來實現。

from selenium import webdriver

browser = webdriver.Chrome()
# 知乎發現頁
browser.get('https://www.zhihu.com/explore')

browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')
browser.execute_script('alert("To Bottom")')

selenium使用過程中,還可以很方便對Cookie進行獲取、添加與刪除等操作。

from selenium import webdriver

browser = webdriver.Chrome()
# 知乎發現頁
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. 反屏蔽

發現美團直接給Selenium給屏蔽了,不知道怎麼搞!!

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/MURTZ9yl5FXnmxSc0Hho9w