Selenium 函数库
selenium 函数库 ( 模组 ) 是使用 Python 进行网络爬虫时,必备的函数库之一,透过 selenium 可以模拟出用户在浏览器的所有操作行为 ( 点击按钮、输入账号密码、卷动卷轴...等 ),因此除了爬虫的应用,也常作为“自动化测试”使用的工具,在网站开发完成后,透过自动化的脚本测试所有功能是否正常,这篇教学将会介绍 selenium 函数库的常见用法,更多用法可前往阅读 selenium 官方文件。
执行 selenium 会启动 chromedriver,所以所以请使用本机环境 ( 参考:使用 Python 虚拟环境 ) 或使用 Anaconda Jupyter 进行实作 ( 参考:使用 Anaconda ) 。
快速导览:
安装 selenium 模组
在本机环境输入下列指令,就能安装 selenium 函数库 ( 依据每个人的作业环境不同,可使用 pip 或 pip3 或 pipenv,Anaconda Jupyter 的安装指令为 !pip )。
pip install selenium
什么是 Selenium WebDriver
WebDriver 是用来执行并操作浏览器的 API 界面,每一个浏览器都会有各自对应的驱动程序 ( driver ),Selenium 会透过 WebDriver 来直接对浏览器进行操作,将所支援的浏览器进行自动化作业,就如同真的用户在操作。
下载 WebDriver
不同的浏览器会对应不同的 driver,以下提供几种常见的 driver ( 本篇范例使用的是 Chrome ):
下载 Chrome driver 时请,必须下载对应的 Chrome 的版本,点击右上角选单“说明 > 关于 Google Chrome”,可以查看版本。
下载后将 driver 与执行的 Python 文件放在同一个目录下,就比较不需要烦恼执行时路径的问题。
import selenium
要使用 requests 必须先 import selenium 模组,启用 webdriver 的功能。
from selenium import webdriver
使用 WebDriver 打开第一个网页
selenium 与 driver 都安装与准备好之后,下方的程序码执行后,会打开一个新的 Chrome 视窗,里面出现指定的 Google 网页,此时这个新的 Chrome 视窗会标明“受到自动测试软件控制”,表示程序正在控制相关的操作。
webdriver.Chrome(路径) 使用相对路径 chromedriver 和执行的程序位在同一层。
from selenium import webdriver
driver = webdriver.Chrome('./chromedriver') # 指向 chromedriver 的位置
driver.get('https://www.google.com') # 打開瀏覽器,開啟網頁
取得网页元素
要模拟真人操作网页的第一步,就是要知道触碰了哪些网页元素,首先加载 selenium 的 By 模组,接着就能使用 find_element() 搭配参数设定,取得指定的网页元素,下方列出 find_element() 常用参数设定 ( 如果将方法的 element 改为 elements,会以串列方式回传找到的元素 ):
新版本 selenium 取得元素的方法有所变更,本文也一并更新,详细的方法参考:selenium.webdriver.remote.webelement
| 参数 | 说明 |
|---|---|
| By.ID, id | 透过 id,寻找第一个相符的网页元素。 |
| By.CLASS_NAME, class | 透过 class,寻找第一个相符的网页元素。 |
| By.CSS_SELECTOR, css selector | 透过 css 选择器,寻找第一个相符的网页元素。 |
| By.NAME, name | 透过 name 属性,寻找第一个相符的网页元素。 |
| By.TAG_NAME, tag | 透过 HTML tag,寻找第一个相符的网页元素。 |
| By.LINK_TEXT, text | 透过超链接的文字,寻找第一个相符的网页元素 |
| By.PARTIAL_LINK_TEXT, text | 透过超链接的部分文字,寻找第一个相符的网页元素。 |
| By.XPATH, xpath | 透过 xpath 的方式,寻找第一个相符的网页元素。 |
下方的程序会用 selenium 打开范例网址 ( 网址链接 ),打开后会用上述的方法,选取特定的网页元素,接着套用点击的方法,依序点击各个按钮,最后会连续打开两次 Google 网站。
范例网址已经有做过点击的处理,点击按钮或下拉选单切换时,上方空格会显示对应的文字。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select # 使用 Select 對應下拉選單
import time
driver = webdriver.Chrome('./chromedriver')
driver.get('https://example.oxxostudio.tw/python/selenium/demo.html') # 開啟範例網址
a = driver.find_element(By.ID, 'a') # 取得 id 為 a 的網頁元素 ( 按鈕 A )
b = driver.find_element(By.CLASS_NAME, 'btn') # 取得 class 為 btn 的網頁元素 ( 按鈕 B )
c = driver.find_element(By.CSS_SELECTOR, '.test') # 取得 class 為 test 的網頁元素 ( 按鈕 C )
d = driver.find_element(By.NAME, 'dog') # 取得屬性 name 為 dog 的網頁元素 ( 按鈕 D )
h1 = driver.find_element(By.TAG_NAME, 'h1') # 取得 tag h1 的網頁元素
link1 = driver.find_element(By.LINK_TEXT, '我是超連結,點擊會開啟 Google 網站') # 取得指定超連結文字的網頁元素
link2 = driver.find_element(By.PARTIAL_LINK_TEXT, 'Google') # 取得超連結文字包含 Google 的網頁元素
select = Select(driver.find_element(By.XPATH, '/html/body/select')) # 取得 html > body > select 這個網頁元素
a.click() # 點擊 a
print(a.text) # 印出 a 元素的內容
time.sleep(0.5)
b.click() # 點擊 b
print(b.text) # 印出 b 元素的內容
time.sleep(0.5)
c.click() # 點擊 c
print(c.text) # 印出 c 元素的內容
time.sleep(0.5)
d.click() # 點擊 d
print(d.text) # 印出 d 元素的內容
time.sleep(0.5)
select.select_by_index(2) # 下拉選單選擇第三項 ( 第一項為 0 )
time.sleep(0.5)
h1.click() # 點擊 h1
time.sleep(0.5)
link1.click() # 點擊 link1
time.sleep(0.5)
link2.click() # 點擊 link2
print(link2.get_attribute('href')) # 印出 link2 元素的 href 屬性
操作网页元素
使用 Selenium 函数库操作网页元素下列几种方法:
| 方法 | ActionChains 参数 | 说明 |
|---|---|---|
| click() | element | 按下鼠标左键。 |
| click_and_hold() | element | 鼠标左键按著不放。 |
| double_click() | element | 连续按两下鼠标左键。 |
| context_click() | element | 按下鼠标右键 ( 需搭配指定元素定位 )。 |
| drag_and_drop() | source, target | 点击 source 元素后,移动到 target 元素放开。 |
| drag_and_drop_by_offset() | source, x, y | 点击 source 元素后,移动到指定的座标位置放开。 |
| move_by_offset() | x, y | 移动鼠标座标到指定位置。 |
| move_to_element() | element | 移动鼠标到某个元素上。 |
| move_to_element_with_offset() | element, x, y | 移动鼠标到某个元素的相对座标位置。 |
| release() | element | 放开鼠标。 |
| send_keys() | values | 送出某个键盘按键值。 |
| send_keys_to_element() | element, values | 向某个元素发送键盘按键值。 |
| key_down() | value | 按著键盘某个键。 |
| key_up() | value | 放开键盘某个键。 |
| reset_actions() | 清除储存的动作 ( 实测没有作用,查讯后是 Bug )。 | |
| pause() | seconds | 暂停动作。 |
| perform() | 执行储存的动作。 |
要使用这些方法的方式有两种,第一种就是“针对指定元素呼叫方法”,例如上方例子的 click() 方法,只要针对指定的元素,呼叫指定的方法,就会执行对应的动作,第二种是使用“ActionChains”,将所有需要执行的方法串成“链”,全部完成后执行 perform() 执行所有的过程。
下方的程序使用“针对指定元素呼叫方法”。
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Chrome('./chromedriver')
driver.get('https://example.oxxostudio.tw/python/selenium/demo.html')
a = driver.find_element(By.ID, 'a')
add = driver.find_element(By.ID, 'add')
a.click() # 點擊按鈕 A,出現 a 文字
sleep(1)
add.click() # 點擊 add 按鈕,出現 數字 1
add.click() # 點擊 add 按鈕,出現 數字 2
sleep(1)
add.click() # 點擊 add 按鈕,出現 數字 3
sleep(1)
add.click() # 點擊 add 按鈕,出現 數字 4
下方的程序使用“ActionChains”的方式,结果与上述的执行结果相同。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Chrome('./chromedriver')
driver.get('https://example.oxxostudio.tw/python/selenium/demo.html')
a = driver.find_element(By.ID, 'a')
add = driver.find_element(By.ID, 'add')
actions = ActionChains(driver) # 使用 ActionChains 的方式
actions.click(a).pause(1) # 點擊按鈕 A,出現 a 文字後,暫停一秒
actions.double_click(add).pause(1).click(add).pause(1).click(add)
# 連點 add 按鈕,等待一秒後再次點擊,等待一秒後再次點擊
actions.perform() # 執行儲存的動作
虽然“针对指定元素呼叫方法”看起来满直觉,但相对来说能使用的方法有限 ( 只能使用 click、send_keys...等两三种 ),使用“ActionChains”才能完整发挥所有的方法,下方的程序码执行后,会自动在输入框内输入指定的文字。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Chrome('./chromedriver')
driver.get('https://example.oxxostudio.tw/python/selenium/demo.html')
a = driver.find_element(By.ID, 'a')
show = driver.find_element(By.ID, 'show')
actions = ActionChains(driver)
actions.click(show).send_keys(['1','2','3','4','5']) # 輸入 1~5 的鍵盤值 ( 必須是字串 )
actions.pause(1) # 等待一秒
actions.click(a) # 點擊按鈕 A
actions.pause(1) # 等待一秒
actions.send_keys_to_element(show, ['A','B','C','D','E']) # # 輸入 A~E 的鍵盤值
actions.perform() # 送出動作
取得网页元素的内容
Selenium 不仅能模拟真人去控制网页元素,也可以取得网页元素的相关内容,甚至进一步执行网页截图并储存的功能,常用的内容如下:
| 内容 | 说明 |
|---|---|
| text | 元素的内容文字。 |
| get_attribute | 元素的某个 HTML 属性值。 |
| id | 元素的 id。 |
| tag_name | 元素的 tag 名称。 |
| size | 元素的长宽尺寸。 |
| screenshot | 将某个元素截图并储存为 png。 |
| is_displayed() | 元素是否显示在网页上。 |
| is_enabled() | 元素是否可用。 |
| is_selected() | 元素是否被选取。 |
| parent | 元素的父元素。 |
下方的程序码执行后,会取得元素的 id、内容文字、tag 名称、尺寸和属性值,最后会将整张网页截图为 test.png。
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome('./chromedriver')
driver.get('https://example.oxxostudio.tw/python/selenium/demo.html')
body = driver.find_element(By.TAG_NAME, 'body')
a = driver.find_element(By.ID, 'a')
b = driver.find_element(By.CLASS_NAME, 'btn')
c = driver.find_element(By.CSS_SELECTOR, '.test')
d = driver.find_element(By.NAME, 'dog')
link1 = driver.find_element(By.LINK_TEXT, '我是超連結,點擊會開啟 Google 網站')
link2 = driver.find_element(By.PARTIAL_LINK_TEXT, 'Google')
print(a.id)
print(b.text)
print(c.tag_name)
print(d.size)
print(link1.get_attribute('href'))
print(link2.get_attribute('target'))
body.screenshot('./test.png')
搭配 JavaScript,发挥最大效益
Selenium 除了内建的方法,也可以搭网页的 JavaScript,发挥网页控制的最大效益,下方的程序码执行后,会先上下滚动网页卷轴,接着弹出提示视窗,两秒后再关闭提示视窗。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.alert import Alert
from time import sleep
driver = webdriver.Chrome('./chromedriver')
driver.get('https://www.selenium.dev/selenium/docs/api/py/webdriver_remote/selenium.webdriver.remote.webelement.html')
sleep(1)
driver.execute_script('window.scrollTo(0, 500)') # 捲動到 500px 位置
sleep(1)
driver.execute_script('window.scrollTo(0, 2500)') # 捲動到 2500px 位置
sleep(1)
driver.execute_script('window.scrollTo(0, 0)') # 捲動到 0px 位置
h1 = driver.find_element(By.TAG_NAME, 'h1')
h3 = driver.find_element(By.TAG_NAME, 'h3')
script = '''
let h1 = arguments[0];
let h3 = arguments[1];
alert(h1, h3)
'''
driver.execute_script(script, h1, h3) # 執行 JavaScript,印出元素
sleep(2)
Alert(driver).accept() # 點擊提示視窗的確認按鈕,關閉提示視窗
参考数据
Selenium 函数库不仅能应用于自动化测试,对于爬虫的应用而言也是必备的函数库,下方列出 Selenium 的官方文件,如果要了解更详细的信息可以前往阅读:
- Selenium 官方网站:API 文件
- 取得网页元素:selenium.webdriver.remote.webelement
- 操作网页元素:selenium.webdriver.common.action_chains
- 控制下拉选单:selenium.webdriver.support.select
- 检查网页元素:selenium.webdriver.support.expected_conditions
- 等待:selenium.webdriver.support.wait
微信扫码关注
抖音扫码关注