---
# System prepended metadata

title: Selenium 的網頁測試應用(含免安裝解決方案)
tags: [Java, Python, Selenium]

---

# Selenium 的網頁測試應用(含免安裝解決方案)
<br> 

##  **概述**

Selenium 是支援 Python 的網路爬蟲套件，透過辨識頁面元素，能支援操作鍵盤輸入、下拉選單、滑鼠操作等動作，從而取代手動動作，實現自動化的網頁操作甚至產出測試報告  
  
Selenium 由三部分構成：WebDriver+IDE+Selenium Grid
* **IDE** : 方便編輯**語法**或錄製操作流程，未必要用 Selenium 的
* **WebDriver** : Selenium 針對不同瀏覽器有支援的 WebDriver (或下載想用的瀏覽器開源 driver 來使用)
* **Selenium Grid** : 佈署多台電腦同時測試才會用到，本篇文章不說明  
<br> 

![](https://i.imgur.com/A0u7aPm.png)
<br> 


## **為 Selenium 安裝 driver**

查看自己瀏覽器版本並下載對應 WebDriver，或使用 Selenium IDE
[Chrome]( https://sites.google.com/chromium.org/driver/downloads )
[FireFox]( https://github.com/mozilla/geckodriver/releases )
[Edge]( https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/ )

下載後呼叫使用→
```python=
from selenium import webdriver

driver = webdriver.Chrome("放置driver的路徑")
```
或直接 import Selenium 的 driver 來用→
```java=
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
...
        WebDriver driver = new FirefoxDriver();
```
<br> 


## **Selenium 應用**


### **主要寫法分為「指定元素操作」、「ActionChains」**


### 針對指定元素呼叫方法

抓特定元素建成物件，再調用方法動作

```python=
from selenium import webdriver
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 屬性
```
<br> 

**↓**
<br> 

![](https://steam.oxxostudio.tw/webp/python/spider/selenium-04.gif)

<br> 

### 使用 ActionChains 將想做的動作串成「鍊」

```python=
from selenium import webdriver
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()   # 送出動作
```
<br> 

**↓**
<br> 

![image alt](https://steam.oxxostudio.tw/webp/python/spider/selenium-06.gif)
<br> 


## **常見解決方案**


要利用 Selenium 至少有下列方法:
* **安裝微軟 Power Automate 使用 Selenium IDE 流程**
* **安裝 Anaconda 直接寫 Python**
* **在 console pip install 裝來用**
* **裝 Selenium IDE 或 Katalon Recorder**
<br> 

### 微軟 Power Automate 使用 Selenium IDE 流程

1. 以往只要在 Power Automate 線上建立**其他桌面流程**即可選擇 **Selenium IDE 流程**來錄製腳本
https://asia.flow.microsoft.com/zh-tw/

2. 然而**其他桌面流程**選項已消失(應該是整併到**桌面流程**內)，而所有桌面流程均要求下載**電腦版 Power Automate**才可使用；透過**雲端流程**則無法選擇 **Selenium IDE 流程**

3. 相關限制如下

> 不支援多重要素驗證 (MFA)，請使用不需要 MFA 的租用戶。
> 
> 不支援這些 Selenium IDE 命令：Run、AnswerOnNextPrompt、ChooseCancelOnNextConfirmation、ChooseCancelOnNextPrompt、ChooseOkOnNextConfirmation、Debugger、ClickAt、DoubleClickAt、Echo、MouseOut、MouseUpAt，以及 MouseDownAt。
> 
> Selenium IDE 動作或步驟要執行，就不能超過一分鐘。 請改用 Power Automate。
> 
> **不支援按一下滑鼠右鍵。**
> 
> 當您使用 Foreach 命令時，系統會產生額外的 Selenium IDE 流程輸入。 若要解決此問題，請在額外的欄位中輸入所有值。 這不會影響播放。
> 
> **直接在 Selenium IDE 中播放可能不會如預期般運作。** 不過，在執行階段會正確播放。

結論，不是很推薦使用。若做功課有爬到這條路基本上不用優先考慮

<br> 



### 安裝 Anaconda 直接寫 Python

1. [安裝 Anaconda](https://steam.oxxostudio.tw/category/python/info/anaconda.html)

2. 在 Anaconda Jupyter 下指令 !pip install selenium

3. 安裝 driver，瀏覽器開源的或官方的都可以

4. 撰寫 python 以執行一系列操作
 
例如 driver.get('URL') 來連線特定 URL

![](https://i.imgur.com/F4VwJ5A.png)
<br> 


### 裝 Selenium IDE 或 Katalon Recorder

[Katalon Recorder](https://chrome.google.com/webstore/detail/katalon-recorder-selenium/ljdobmomdgdljniojadhoplhkpialdid)
[Selenium IDE](https://chrome.google.com/webstore/detail/selenium-ide/mooikfkahbdckldjjndioackbalphokd)

![](https://i.imgur.com/ffBBi46.png)

![](https://i.imgur.com/51JbY0t.png)

**（DEMO環節）**

<br> 



## **其他酷東西**


### XPATH做元素定位(利用Ruto、ChroPath等插件工具)

XPATH：HTML 經過編譯成 XML 後找出的對應位置，且分為絕對位置與相對位置
> 相對位置：//div[@class='ytp-tooltip-text-wrapper']
> 絕對位置： /html[1]/body[1]/ytd-app[1]/div[1]/ytd-page-manager[1]/ytd-watch-flexy[1]/div[5]/div[1]/div[1]/div[1]/div[1]/div[1]/div[1]/ytd-player[1]/div[1]/div[1]/div[10]/div[1]

**安裝[RUTO](https://chrome.google.com/webstore/detail/ruto-xpath-finder/ilcoelkkcokgeeijnopjnolmmighnppp?hl=zh-TW)**

![](https://i.imgur.com/jRFe2bn.png)

**安裝[ChroPath](https://chrome.google.com/webstore/detail/chropath/ljngjbnaijcbncmcnjfhigebomdlkcjo?hl=zh-TW)**

F12後多出ChroPath頁籤方便查找元素：
![](https://i.imgur.com/jhcSCXB.png)
<br> 



### 拍截圖
```python=
body = driver.find_element_by_tag_name('body')
body.screenshot('./test.png')
```

### 跑 JavaScript
```python=
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() # 點擊提示視窗的確認按鈕，關閉提示視窗
```

### 切換視窗
```python=
driver.switch_to.window("windowName")
```

### 使用既有 Profile

若要使用 Google Chrome 中既有的 Profile 來進行測試，可將其作為參數加入 WebDriver：

```python=
from selenium import webdriver

# 設定檔案路徑參數成為自訂的 WebDriver (命名為 options)
options = webdriver.ChromeOptions()
options.add_argument("--user-data-dir=C:UsersOfficeGuideAppDataLocalGoogleChromeUser Data")
options.add_argument("--profile-directory=Profile 1")

# 使用自訂的 WebDriver
browser = webdriver.Chrome(options=options)
```
<br> 


### 列印 PDF 報表(Goodinfo!為例)
```python=
import json
from time import sleep
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
settings = {"recentDestinations": [{"id": "Save as PDF", "origin": "local", "account": ""}],
            "selectedDestinationId": "Save as PDF", "version": 2,
            "isCssBackgroundEnabled": True, "scalingType": 3, "scaling": 100}

#此處記得設定您本地電腦可以存檔的路徑
prefs = {"printing.print_preview_sticky_settings.appState": json.dumps(settings),
         "savefile.default_directory": "C:/Users/user/Downloads"}

options.add_experimental_option('prefs', prefs)
options.add_argument('--kiosk-printing')

#這兩句處理 driver，請設定事前存好的driver 或 remote call來用
webdriver_path = 'D:/Python/CultivationGrid/selenium/chromedriver.exe'
driver = webdriver.Chrome(executable_path=webdriver_path, options=options)

driver.get("https://goodinfo.tw/StockInfo/index.asp")
driver.find_element_by_id("txtStockCode").click()
driver.find_element_by_id("txtStockCode").clear()
driver.find_element_by_id("txtStockCode").send_keys("0050")
driver.find_element_by_xpath(u"//input[@value='股票查詢']").click()
driver.find_element_by_id("imgKC").click()
sleep(5)
driver.execute_script('window.print();')
driver.close()
```
<br> 


### 若有多支py可用BeautifulReport產報表來看

1. 下載BeautifulReport
https://github.com/TesterlifeRaymond/BeautifulReport

2. 資料夾名稱改為 BeautifulReport，放到 python 的 library
例 C:\Users\你的使用者名稱\AppData\Local\Programs\Python\Python39\Lib\site-packages\

3. 
```python=
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions as EC
from BeautifulReport import BeautifulReport
from webdriver_manager.chrome import ChromeDriverManager
import time
import unittest

## 設定Chrome的瀏覽器彈出時遵照的規則
## 這串設定是防止瀏覽器上頭顯示「Chrome正受自動控制」
options = webdriver.ChromeOptions()
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)
## 關閉自動記住密碼的提示彈窗
options.add_experimental_option("prefs", {
    "profile.password_manager_enabled": False,
    "credentials_enable_service": False
})
                              
## 如果要將CASE拆成幾個不同的方法，需要用一個Unitest Class包覆起來，然後加上修飾符@classmethod
class Test(unittest.TestCase):
    @classmethod
    def setUpClass(self):
        self.driver = webdriver.Chrome(chrome_options=options)
        self.action = ActionChains(self.driver)
        ## 開啟Chrome新視窗，前往Youtube網址並最大化視窗
        self.URL = "https://youtube.com"
        self.driver.get(self.URL)
        self.driver.maximize_window()
    
    @classmethod
    def tearDownClass(self):
        self.driver.quit()    #全部做完後關閉瀏覽器
    
    ## Test Case 的命名方式務必以「test_01_* ~ test_99_*」為主，讓爬蟲依照順序走
    def test_01_search(self):
        """
        測項1
        """
    
    def test_02_open_target(self):
        """
        測項2
        """
        
    def test_03_back_to_list(self):
        """
        測項3
        """

# basedir就是存放所有TEST Case的目錄，讓它爬 pattern = '*.py'，所以要做哪個類別的測試就指定哪個前贅
basedir = "D:/auto_test/"
if __name__ == '__main__':
    # 取得資料夾目錄底下，符合後面任何副檔名為.py，並進行所有test的測試項目
    test_suite = unittest.defaultTestLoader.discover(
        basedir, pattern='*.py')

    # 測試結果加入到 BeautifulReport 套件內
    result = BeautifulReport(test_suite)

    # 結果產生Report 檔案名稱為 filename, 敘述為 description, log_path 預設放在跟目錄底下就行
    result.report(filename='report',
                  description='我的第一個測試', log_path='D:/auto_test/')
```
**↓**
![](https://i.imgur.com/2aMtny1.png)
<br> 

### 做好的腳本可以用 Robointern 在本地電腦排程執行
[Robointern](https://robointern.tech/#screens)
<br> 


## **參考資料**

[Microsoft Build 建立及測試 Selenium IDE 流程](https://docs.microsoft.com/zh-tw/power-automate/desktop-flows/create-web)
[ Steam教育網 Selenium 函式庫 ]( https://steam.oxxostudio.tw/category/python/spider/selenium.html )
[Selenium 是什麼？用 Python Selenium 自動爬網頁抓報表，初學者必看的簡單教學 ]( https://igoamazing.com/python-selenium/#1_%E9%8C%84%E8%A3%BD%E4%B8%A6%E8%87%AA%E5%8B%95%E7%94%A2%E7%94%9F%E7%A8%8B%E5%BC%8F%E7%A2%BC )
[Python Selenium with VSCODE 教學筆記 ]( https://hackmd.io/@FortesHuang/S1V6jrvet#Python-Selenium-with-VSCODE-%E6%95%99%E5%AD%B8%E7%AD%86%E8%A8%98 )

###### tags: `Java`,`Python`,`Selenium`