Node 使用 Selenium 進行前端自動化操做

Node 使用 Selenium 進行前端自動化操做

前言:
最近項目中有相似的需求:須要對前端項目中某一個用戶下的產品數據進行批量的處理。手動處理的流程大概是首先登陸系統,獲取到當前用戶下的產品列表,點擊產品列表的中產品項進入詳情頁,對該產品進行一系列的操做,而後保存退出。由於當前有20多萬條數據,手動一條一條的處理不太現實,因此但願經過寫腳本的方式來進行處理。

需求分析

其實這個需求還算比較簡單,須要實現的點主要有三個,一是如何進行登陸,獲取登陸信息,查詢當前用戶下的產品數據;二是如何知道當前數據是否處理完,而後退出當前的處理流程;三是如何異步的處理一批數據。javascript

因此須要作的工做就是模擬登陸,調用產品列表的查詢接口獲取產品ID集合,而後循環遍歷當前的集合,經過產品ID跳轉產品詳情頁面,模擬頁面按鈕的點擊操做,監聽處理完成的動做,退出當前的流程。css

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自動化以及框架的核心技術。html

Selenium 主要分 Selenium WebDriver 以及 Selenium IDE。我主要結合Node來介紹 Selenium WebDriver 的安裝使用。本文主要介紹Selenium 結合 Node 的安裝使用。須要進行深刻研究的同窗請自行查看官網文檔前端

Node 環境搭建

1. node的安裝在此再也不贅述。點擊連接查看官網下載安裝方法。
2. express安裝java

$ npx express-generator

或者node

$ npm install -g express-generator

建立項目:jquery

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

啓動項目:ios

$ DEBUG=myapp:* yarn start

至此,Node 項目建立完畢。接下來咱們就能夠在項目中集成Selenium WebDrivergit

Selenium WebDriver 集成

1. 安裝selenium-webdrivergithub

yarn add selenium-webdriver

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

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

開始使用

進入咱們剛纔建立的項目文件夾,目錄以下:

clipboard.png

  1. 頁面添加一個開始按鈕,以及給按鈕添加事件。
    找到 views/index.ejs, 添加以下代碼:(爲了方便操做,引入了jquery, axios, 因此須要下載準備好)

    clipboard.png

    clipboard.png

  2. 添加對應的路由

    clipboard.png

    在app.js文件中,引入路由chromeDriver

    var chromeDriverRouter = require('./routes/chromeDriver');
     app.use('/chromeDriver', chromeDriverRouter);
  3. 引入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();
         }
     }
  4. 啓動服務,查看效果。
    啓動服務以後,我夢能看到以下的界面。
    clipboard.png
    點擊頁面中的【點擊開始】按鈕,最終可以看到以下的界面,爲了演示我作了兩秒的延遲。生成的gif圖有9M多,沒法上傳。後續能夠下載源碼運行看效果。
    clipboard.png
  5. 獲取登陸信息
    以上是selenium-webdriver的簡單集成。在以前咱們提到過實際需求中如何獲取登陸信息的問題。在訪問產品列表頁面的時候須要進行登陸校驗。若是沒有登陸則會跳轉界面。因爲咱們的登陸頁是經過iframe來嵌套引入的。因爲暫時尚未了解如何處理iframe裏的操做,因此無法去模擬用戶名密碼的輸入。
    查看API文檔,WebDriver 會有一個manage方法:

    this.manage() → Options

    該方法會返回一個Options實例,具備以下的方法:
    clipboard.png
    其中有對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地址

相關文章
相關標籤/搜索