前言:
最近項目中有相似的需求:須要對前端項目中某一個用戶下的產品數據進行批量的處理。手動處理的流程大概是首先登陸系統,獲取到當前用戶下的產品列表,點擊產品列表的中產品項進入詳情頁,對該產品進行一系列的操做,而後保存退出。由於當前有20多萬條數據,手動一條一條的處理不太現實,因此但願經過寫腳本的方式來進行處理。
其實這個需求還算比較簡單,須要實現的點主要有三個,一是如何進行登陸,獲取登陸信息,查詢當前用戶下的產品數據;二是如何知道當前數據是否處理完,而後退出當前的處理流程;三是如何異步的處理一批數據。javascript
因此須要作的工做就是模擬登陸,調用產品列表的查詢接口獲取產品ID集合,而後循環遍歷當前的集合,經過產品ID跳轉產品詳情頁面,模擬頁面按鈕的點擊操做,監聽處理完成的動做,退出當前的流程。css
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 的安裝使用。須要進行深刻研究的同窗請自行查看官網文檔。前端
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
1. 安裝selenium-webdrivergithub
yarn add selenium-webdriver
2. 下載安裝支持不一樣瀏覽器的驅動。(此處只介紹Chrome驅動)
[ChromeDriver][3] 下載並解壓文件,同時把解壓的執行文件放置到 /usr/bin目錄下。或者設置相應的PATH路徑,確保可執行文件在PATH路徑中。
進入咱們剛纔建立的項目文件夾,目錄以下:
添加對應的路由
在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(); } }
獲取登陸信息
以上是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進入產品詳情頁。而後再模擬頁面按鈕點擊操做便可。