1. 程式人生 > 實用技巧 >Node使用Selenium進行前端自動化操作的程式碼實現

Node使用Selenium進行前端自動化操作的程式碼實現

前言:

最近專案中有類似的需求:需要對前端專案中某一個使用者下的產品資料進行批量的處理。手動處理的流程大概是首先登入系統,獲取到當前使用者下的產品列表,點選產品列表的中產品項進入詳情頁,對該產品進行一系列的操作,然後儲存退出。因為當前有20多萬條資料,手動一條一條的處理不太現實,所以希望通過寫指令碼的方式來進行處理。

需求分析

其實這個需求還算比較簡單,需要實現的點主要有三個,一是如何進行登入,獲取登入資訊,查詢當前使用者下的產品資料;二是如何知道當前資料是否處理完,然後退出當前的處理流程;三是如何非同步的處理一批資料。

所以需要做的工作就是模擬登入,呼叫產品列表的查詢介面獲取產品ID集合,然後迴圈遍歷當前的集合,通過產品ID跳轉產品詳情頁面,模擬頁面按鈕的點選操作,監聽處理完成的動作,退出當前的流程。

Selenium 介紹

What is Selenium?
Selenium automates browsers. That's it! What you do with that power is entirely up to you. Primarily, it is for automating web applications for testing purposes, but is certainly not limited to just that. Boring web-based administration tasks can (and should!) be automated as well.
Selenium has the support of some of the largest browser vendors who have taken (or are taking) steps to make Selenium a native part of their browser. It is also the core technology in countless other browser automation tools, APIs and frameworks.

翻譯過來大致意思就是: Selenium 可以自動化操作瀏覽器。怎麼去使用Selenium 的功能完全取決於我們自己。它主要還是使用在web應用的自動化測試上。但是他的功能並不僅限於此。那些枯燥的基於web的管理任務也可以自動化。很多流行的瀏覽器都採取了一些措施來支援Selenium實現本地化。它也是很多瀏覽器自動化工具、API自動化以及框架的核心技術。

Selenium 主要分 Selenium WebDriver 以及 Selenium IDE。我主要結合Node來介紹 Selenium WebDriver 的安裝使用。本文主要介紹Selenium 結合 Node 的安裝使用。需要進行深入研究的同學請自行檢視官網文件。

Node 環境搭建

1. node的安裝在此不再贅述。點選連結檢視官網下載安裝方法。
2. express安裝

$ npx express-generator

或者

$ npm install -g express-generator

建立專案:

$ express --view=ejs selenium-start
$ cd selenium-start
$ yarn

啟動專案:

$ DEBUG=myapp:* yarn start

至此,Node 專案建立完畢。接下來我們就可以在專案中整合Selenium WebDriver

Selenium WebDriver 整合

1. 安裝selenium-webdriver

yarn add selenium-webdriver

2. 下載安裝支援不同瀏覽器的驅動。(此處只介紹Chrome驅動)

[ChromeDriver][3]
下載並解壓檔案,同時把解壓的執行檔案放置到 /usr/bin目錄下。或者設定相應的PATH路徑,確保可執行檔案在PATH路徑中。

開始使用

進入我們剛才建立的專案資料夾,目錄如下:

頁面新增一個開始按鈕,以及給按鈕新增事件。

找到 views/index.ejs, 新增如下程式碼:(為了方便操作,引入了jquery, axios, 所以需要下載準備好)

新增對應的路由

在app.js檔案中,引入路由chromeDriver

 var chromeDriverRouter = require('./routes/chromeDriver');
 app.use('/chromeDriver', chromeDriverRouter);

引入selenium-webdriver

在routes/chromeDirver.js檔案中,我們添加了一個方法handleBaiDuDriver,這個方法用於處理模擬百度搜索自動化的一些測試。

首先我們需要在檔案頂部引入selenium-webdriver

 const {Builder, By, Key, until} = require('selenium-webdriver');

 // Builder: 用於建立一個WebDriver例項。
 // By: 表示通過什麼方式來查詢頁面的元素。
   // By.className( name ) → By
   // By.css( selector ) → By
   // By.id( id ) → By
   // By.js( script, ...var_args ) → function(WebDriver): Promise
   // By.linkText( text ) → By
   // By.name( name ) → By
   // By.partialLinkText( text ) → By
 // Key: 表示鍵盤上一系列的按鍵。
 // until: 定義了一些工具類的方法。

然後書寫我們的方法體裡的內容。

const handleBaiDuDriver = async () => {
   let driver = await new Builder().forBrowser('chrome').build();
   try {
     await driver.get('http://www.baidu.com');
 
     await driver.findElement(By.id('kw')).sendKeys('webdriver', Key.RETURN);//正常使用
 
     await driver.findElement(By.id('su')).click();
 
     await driver.wait(until.titleIs('百度一下,你就知道'), 1000);
     
   } catch (error) {
     console.log(error)
   } finally {
     await driver.sleep(2000);
     await driver.quit();
   }
 }

啟動服務,檢視效果。

啟動服務之後,我夢能看到如下的介面。

點選頁面中的【點選開始】按鈕,最終能夠看到如下的介面,為了演示我做了兩秒的延遲。生成的gif圖有9M多,無法上傳。後續可以下載原始碼執行看效果。

獲取登入資訊

以上是selenium-webdriver的簡單整合。在之前我們提到過實際需求中如何獲取登入資訊的問題。在訪問產品列表頁面的時候需要進行登入校驗。如果沒有登入則會跳轉介面。由於我們的登入頁是通過iframe來巢狀引入的。由於暫時還沒有了解如何處理iframe裡的操作,所以沒法去模擬使用者名稱密碼的輸入。

檢視API文件,WebDriver 會有一個manage方法:

this.manage() → Options

該方法會返回一個Options例項,具有如下的方法:

其中有對cookie的操作方法。所以可以通過首次輸入使用者資訊並進行快取的方式來實現登入態的儲存。在下一次再開啟頁面的時候直接從快取裡獲取cookie資訊,並通過addCookie方法進行cookie的設定。但是由於我不知道什麼時候、多長時間登入才會成功,所以在獲取cookie的時候需要通過不斷迴圈的方式去獲取,直到拿到cookie。當然可以設定一個超時時間。超時之後就退出當前driver。

 
 // 快取cookie
 async function setCookies(driver) {
   const manage = driver.manage();
   let sleepTime = 6000;
   await driver.sleep(sleepTime);
   let cookies = null
   try {
     cookies = await manage.getCookies();  
   } catch (error) {
   }
   while (!cookies || !findSessionIdFromCookies(cookies)) {
     await driver.sleep(2000)
     sleepTime += 2000;
     try {
       cookies = await manage.getCookies();
     } catch (error) {
     }
   }
   if (cookies && findSessionIdFromCookies(cookies)) {
     cache.cookies = cookies; // cache是全域性用於快取cookie的物件
     cache.cookiesStr = cache.cookies.map((cookie) => {
       return `${cookie.name}=${cookie.value}`
     }).join(';');
   }
   return cookies;
 }
 
 
 // 設定cookie
 async function initCookies(driver) {
   const cookies = cache.cookies;
   if (cookies && cookies.length > 0) {
     await driver.manage().deleteAllCookies();
     for (let i = 0 ; i < cookies.length; i++) {
       cookie = cookies[i];
       await driver.manage().addCookie(cookie);    
     };
   }
 }

獲取到cookie 資訊之後就可以請求產品列表以及通過產品ID進入產品詳情頁。然後再模擬頁面按鈕點選操作即可。

Github地址

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援碼農教程。