用Electron寫個帶界面的nodejs爬蟲的實(shí)現(xiàn)方法
什么是Electron
使用 JavaScript, HTML 和 CSS 構(gòu)建跨平臺的桌面應(yīng)用
[官網(wǎng)](https://electronjs.org/)
實(shí)質(zhì)就是一個精簡的Webkit瀏覽器顯示html頁面,通過electron做中間層可以和系統(tǒng)交流。給web項(xiàng)目套上一個node環(huán)境的殼。
前言
公司買的推廣居然沒有后臺的api,沒有api又不想死板手動操作。那就做個爬蟲吧。但是又是給小白用的,自然最好帶個界面,本來用C#拖出來就好了,看到vs那么大,下載都要半天。干脆就用Electron做一個,順便學(xué)習(xí)一下Electron。
準(zhǔn)備工作
安裝nodejs
npm安裝electron(最好換成cnpm,不然可能失敗)
hello world
官方提供了快速開始的手腳架,怎么方便怎么來。
https://github.com/atom/electron-quick-start
clone下來

git那些不是我們需要的,就刪掉。
安裝相關(guān)的依賴,推薦用yarn。
yarn https://yarn.bootcss.com/
cd 到 目錄下
cnpm install yarn yarn
等待依賴安裝完成。
npm run start
順利的話就可以看到程序啟動。

界面編寫
準(zhǔn)備完畢,開始進(jìn)入正題。
用vscode打開文件夾,順帶一提,vscode也是基于electron。vscode不愧是巨硬出品,越來越好用了。
整理一下

這里就不累贅了。
后臺有多個小號要登錄,就寫個登錄頁面。
編輯一下index.html
<html>
<head>
<meta charset="utf-8">
<link rel="external nofollow" rel="stylesheet">
</head>
<body>
<div class="panel panel-default" style="margin: 10px">
<div class="panel-body">
<div class="form-horizontal" role="form">
<div class="form-group">
<label for="input_name" class="col-sm-2 control-label">登錄帳號</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="input_name" placeholder="請輸入用戶名">
</div>
</div>
<div class="form-group">
<label for="input_pass" class="col-sm-2 control-label">登錄密碼</label>
<div class="col-sm-10">
<input type="password" class="form-control" id="input_pass" placeholder="請輸入登錄密碼">
</div>
</div>
<div class="form-group">
<label for="input_check" class="col-sm-2 control-label">驗(yàn)證碼:</label>
<div class="col-sm-6">
<input type="text" class="form-control" id="input_check" placeholder="請輸入驗(yàn)證碼">
</div>
<div class="col-sm-2">
<img id="img_code" src="code.png" />
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-2">
<button id="btn_submit" class="btn btn-default">登錄</button>
</div>
<div class="col-sm-2">
<button id="btn_refresh" class="btn btn-default">刷新驗(yàn)證碼</button>
</div>
</div>
</div>
</div>
</div>
<script>
require('./index.js');
</script>
</body>
</html>
都是些 很簡單的html代碼,為了好看的就用了bootstrap
electron可以調(diào)用bootstap、jquery ,方便開發(fā)。調(diào)用jq有個小小的坑,注意一下。
不過我這里不需要什么效果,就簡單點(diǎn)。
在vscode 快捷鍵 Ctrl + ` 調(diào)出 CMD 運(yùn)行一下
npm run start
就可以看到我們剛剛寫的網(wǎng)頁了

下載驗(yàn)證碼
登錄是需要驗(yàn)證碼的,我們把驗(yàn)證碼下載下來。
流程是 請求驗(yàn)證碼網(wǎng)站,下載驗(yàn)證碼保存到本地顯示,驗(yàn)證碼的cookie保存下來,后面登錄時候需要用到cookie
安裝需要的依賴 superagent , fs-extra
編輯 main.js
const electron = require('electron')
const app = electron.app
const BrowserWindow = electron.BrowserWindow
const path = require('path')
const url = require('url')
// 爬蟲
const superagent = require('superagent');
// 操作文件
const fs = require('fs-extra');
let mainWindow
// 驗(yàn)證碼的cookie
var codeCookie
// 驗(yàn)證碼網(wǎng)址
const codeUrl = '驗(yàn)證碼地址';
// 頭信息
const browserMsg = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
};
function createWindow() {
mainWindow = new BrowserWindow({
width: 800,
height: 600
})
superagent
.get(codeUrl)
.set(browserMsg)
.end((err, res) => {
codeCookie = res.header['set-cookie']
console.log('codeCookie: ' + codeCookie)
// 驗(yàn)證碼圖片保存到本地
fs.outputFile(path.join(__dirname) + '/code.png', res.body, function (err) {})
})
mainWindow.loadURL(url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes: true
}))
// 打開調(diào)試控制臺
mainWindow.webContents.openDevTools()
mainWindow.on('closed', function () {
mainWindow = null
})
}
app.on('ready', createWindow)
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
if (mainWindow === null) {
createWindow()
}
})
說一下安裝的依賴
fs-extra fs-extra模塊是系統(tǒng)fs模塊的擴(kuò)展,提供了更多便利的 API,并繼承了fs模塊的 API。
主角就是 superagent https://www.npmjs.com/package/superagent
運(yùn)行一下


很好,我們要的驗(yàn)證碼和cookie 都有了。
分析登錄流程
用 Fiddler 抓包工具和瀏覽器的調(diào)試控制臺分析一下后臺的登錄。
這里不是重點(diǎn)就略過了。
Electron 通信
渲染進(jìn)程(就是網(wǎng)頁) 登錄 需要 主進(jìn)程保存的codeCookie ,這就要兩者進(jìn)行通信。
Electron之間的通信是用ipc
主進(jìn)程的是 ipcMain 也可以用 mainWindow.webContents來發(fā)送
渲染進(jìn)程的是 ipcRenderer
這里演示一下 主進(jìn)程發(fā)送cookie 給 渲染進(jìn)程
main.js 文件
const ipcMain = electron.ipcMain;
ipcMain.on('notice', (e, msg) => {
switch (msg) {
case 'getcodeCookie':
mainWindow.webContents.send('codeCookie',codeCookie)
break
default:
break
}
})
打開調(diào)試控制臺 可以看到輸出
index.js
const electron = require('electron');
const ipcRenderer = electron.ipcRenderer;
// 獲取控件
let btn_submit = document.getElementById("btn_submit");
btn_submit.addEventListener('click', (e) => {
ipcRenderer.send('notice', 'getcodeCookie');
});
// 監(jiān)聽 codeCookie
ipcRenderer.on('codeCookie', (e, msg) => {
codeCookie = msg;
console.log('接受主進(jìn)程發(fā)送的codeCookie: '+codeCookie);
});
運(yùn)行一下, 點(diǎn)擊登錄按鈕
就可以在調(diào)試控制臺看到 codeCookie

模擬登錄
我們需要登錄后臺,獲取登錄后cookie這樣才方便我們操作。
編輯index.js
const electron = require('electron');
const ipcRenderer = electron.ipcRenderer;
const path = require('path');
const superagent = require('superagent');
// 鏈接
const urls = {
loginUrl: "登錄的地址",
codeUrl: "驗(yàn)證碼地址",
targetUrl: "后臺的地址"
};
// 頭信息
const browserMsg = {
"User-Agent": "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36",
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
};
// 驗(yàn)證碼cookie
var codeCookie;
// 登錄后的cookie
var tokenCookie;
// 獲取控件
const btn_submit = document.getElementById("btn_submit");
const btn_refresh = document.getElementById("btn_refresh");
const input_name = document.getElementById("input_name");
const input_pass = document.getElementById("input_pass");
const input_code = document.getElementById("input_code");
// 登錄按鈕 點(diǎn)擊事件
btn_submit.addEventListener('click', (e) => {
ipcRenderer.send('notice', 'getcodeCookie');
// 獲取輸入文本
var name = input_name.value;
var pass = input_pass.value;
var code = input_check.value;
// 校驗(yàn)輸入
if (name == "" || pass == "" || code == "") {
alert("請輸入");
} else {
// 校驗(yàn)通過 開始進(jìn)行登錄操作
superagent
.post(urls.loginUrl)
.set('Cookie', codeCookie)
.set(browserMsg)
// 避免登錄后的302重定向
.redirects(0)
.send({
'LoginForm[username]': name
}).send({
'LoginForm[password]': pass
}).send({
logincode: code
}).send({
jz: '0'
}).end((err, res) => {
// 登錄成功 獲取tokenCookie
// 獲取tokenCookie
tokenCookie = res.header['set-cookie'];
superagent
.get(urls.targetUrl)
.set('Cookie',tokenCookie)
.set(browserMsg)
.end((err,res)=>{
// 成功進(jìn)入后臺
console.log(res.text);
})
});
}
});
btn_refresh.addEventListener('click', (e) => {
});
ipcRenderer.on('codeCookie', (e, msg) => {
codeCookie = msg;
console.log('接受主進(jìn)程發(fā)送的codeCookie: ' + codeCookie);
});
這里只是演示一下代碼怎么寫,具體不一定那么順利的拿到tokenCookie。具體情況具體分析。
關(guān)鍵是請求要帶上cookie
數(shù)據(jù)抓取
成功進(jìn)入到后臺了,就要抓取需要的數(shù)據(jù)了。這里就需要 cheerio 工具了
cheerio https://cheerio.js.org/
可以理解是node上jq , 操作基本跟jq是一樣的。
操作還是很簡單的。
要注意的是nodejs是異步的,就連for也是異步的。
有時候要等待請求完成的話,就要用上 async 了。
導(dǎo)出xlsx表格
爬蟲基本完成了,怎么導(dǎo)出數(shù)據(jù)就隨意了。
如果是要生成xls表格,一般是用excel-export 簡單夠用
我這里推薦 另一個 better-xlsx 。
這里演示一下 , 怎么調(diào)用系統(tǒng)的保存對話框,保存文件。
編輯 index.js
const remote = electron.remote;
btn_refresh.addEventListener('click', (e) => {
const filepath =remote.dialog.showSaveDialog(remote.getCurrentWindow(), {
// 過濾文件類型
filters: [{
name: "xls Files",
extensions: ['xlsx']
},
{
name: 'All Files',
extensions: ['*']
}
]
});
console.log(filepath);
});
運(yùn)行一下,點(diǎn)擊刷新驗(yàn)證碼按鈕就可以看到熟悉的系統(tǒng)對話框
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Nodejs Playwright 2Captcha 驗(yàn)證碼識別實(shí)現(xiàn)自動登陸功能
日常工作當(dāng)中,為了提高工作效率,我們可能會寫腳本來自動執(zhí)行任務(wù),有些網(wǎng)站因?yàn)樾枰脩舻顷?所以腳本的自動登陸功能必不可少,這篇文章主要介紹了Nodejs Playwright 2Captcha 驗(yàn)證碼識別實(shí)現(xiàn)自動登陸功能,需要的朋友可以參考下2024-05-05
Windows8下搭建Node.js開發(fā)環(huán)境教程
這篇文章主要介紹了Windows8下搭建Node.js開發(fā)環(huán)境教程,Win8下安裝node.js也比較簡單,只是一些權(quán)限比較麻煩,需要的朋友可以參考下2014-09-09
基于Node-red的在線評語系統(tǒng)(可視化編程,公網(wǎng)訪問)
Node-Red是IBM公司開發(fā)的一個可視化的編程工具,在網(wǎng)頁內(nèi)編程,主要是拖拽控件,代碼量很小,這篇文章主要介紹了基于Node-red的在線評語系統(tǒng)(可視化編程,公網(wǎng)訪問),需要的朋友可以參考下2022-01-01
3分鐘快速搭建nodejs本地服務(wù)器方法運(yùn)行測試html/js
本篇文章主要介紹了3分鐘快速搭建nodejs本地服務(wù)器方法運(yùn)行測試html/js,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2017-04-04
Node.js+ES6+dropload.js實(shí)現(xiàn)移動端下拉加載實(shí)例
這個demo服務(wù)由Node搭建服務(wù)、下拉加載使用插件dropload,數(shù)據(jù)渲染應(yīng)用了ES6中的模板字符串。有興趣的小伙伴可以自己嘗試下2017-06-06
使用Node.js搭建Vue項(xiàng)目的詳細(xì)步驟
Vue.js 是一款流行的 JavaScript 框架,而 Node.js 提供了一個強(qiáng)大的運(yùn)行環(huán)境,兩者的結(jié)合使得開發(fā)者可以輕松構(gòu)建現(xiàn)代化的前端項(xiàng)目,本文將介紹如何使用 Node.js 搭建一個基本的 Vue 項(xiàng)目,需要的朋友可以參考下2023-12-12
npm?list輸出結(jié)果包含extraneous標(biāo)志記錄分析
這篇文章主要為大家介紹了npm?list輸出結(jié)果包含extraneous標(biāo)志記錄分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01

