本文介绍如何利用Electron框架开发带有图形界面的Node.js爬虫工具。内容涵盖环境配置、主进程与渲染进程间通过IPC进行通信以传递Cookie、使用superagent处理验证码获取及登录模拟,以及利用cheerio解析数据并导出为Excel文件。适合希望将脚本转化为可视化工具的开发者参考。
Electron简介
Electron是一个开源框架,允许开发者使用Web技术构建跨平台桌面应用程序。
它结合了JavaScript、HTML和CSS,使得开发者能够利用现有的Web技能创建原生桌面应用。
访问Electron官方网站获取更多信息:https://electronjs.org/
从技术本质上看,Electron封装了一个精简版的Webkit浏览器来渲染HTML页面,并通过中间层与操作系统进行交互,相当于为Web项目提供了一个Node.js运行环境的外壳。
项目背景与准备
前言
由于公司购买的推广服务缺乏后台API接口,手动操作效率低下且不够灵活,因此决定开发一个爬虫程序。考虑到目标用户群体对技术门槛较为敏感,提供一个图形用户界面(GUI)是必要的。虽然C#等语言适合快速构建界面,但Visual Studio体积庞大且启动缓慢,相比之下,使用Electron开发不仅轻量,还能借此机会深入学习该技术。
准备工作
首先需要确保系统中已安装Node.js环境。
接着通过npm安装Electron依赖。建议将npm源切换为国内镜像(如cnpm),以提高下载成功率并加速安装过程。
快速启动示例
Hello World示例
Electron官方提供了快速启动脚手架,开发者可根据需求选择最便捷的方式开始项目。
官方提供的快速启动仓库地址为:https://github.com/atom/electron-quick-start
将上述仓库克隆到本地目录。

克隆完成后,可以删除与Git相关的版本控制文件,因为对于本项目而言这些并非必需。
安装项目所需的依赖包,推荐使用yarn工具进行管理,因其性能更优。
yarn https://yarn.bootcss.com/
进入项目根目录。
cnpm install yarn
yarn
等待依赖包安装完成。
npm run start
若一切顺利,启动程序即可看到初始界面。

界面开发
界面编写
环境准备就绪后,开始进行核心功能的界面开发。
使用VS Code打开项目文件夹。值得注意的是,VS Code本身也是基于Electron开发的,其日益完善的体验证明了该框架的成熟度。
整理项目结构

此处省略繁琐的结构调整细节。
由于后台需要管理多个账号登录,因此设计一个专门的登录页面。
编辑index.html文件以构建前端界面。
<html>
<head>
<meta charset="utf-8">
<link href="http://apps.bdimg.com/libs/bootstrap/3.3.4/css/bootstrap.min.css" 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">验证码:</label>
<div class="col-sm-6">
<input type="text" class="form-control" id="input_check" placeholder="请输入验证码">
</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">刷新验证码</button>
</div>
</div>
</div>
</div>
</div>
<script>
require('./index.js');
</script>
</body>
</html>
界面代码主要使用基础HTML,为了提升视觉效果,引入了Bootstrap框架。
Electron支持调用Bootstrap和jQuery等前端库,这大大简化了开发流程。不过在使用jQuery时需注意一些兼容性问题。
本例中无需复杂特效,因此保持界面简洁。
在VS Code中使用快捷键Ctrl + `打开终端,运行项目。
npm run start
运行后即可看到刚才编写的网页界面。

验证码获取与依赖
下载验证码
登录过程通常需要验证码,因此需要实现验证码的下载功能。
具体流程为:请求验证码网站,将验证码图片保存至本地并显示,同时获取并保存验证码相关的Cookie,以便后续登录时使用。
安装所需的Node.js依赖库:superagent用于HTTP请求,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
// 验证码的cookie
var codeCookie
// 验证码网址
const codeUrl = '验证码地址';
// 头信息
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)
// 验证码图片保存到本地
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
}))
// 打开调试控制台
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是Node.js原生fs模块的扩展,提供了更便捷的API,同时保留了原生fs的功能。
核心网络请求库为superagent,其官方文档地址为:https://www.npmjs.com/package/superagent
运行程序进行测试。


测试结果显示,验证码图片和对应的Cookie均已成功获取。
登录流程分析
分析登录流程
使用Fiddler抓包工具结合浏览器开发者控制台,分析目标网站的登录机制。
由于抓包细节非本文重点,此处略过具体步骤。
进程间通信机制
Electron进程间通信
渲染进程(即网页部分)在执行登录操作时,需要获取主进程中保存的验证码Cookie,这涉及到两个进程间的通信。
Electron中进程间通信主要使用IPC(Inter-Process Communication)机制。
主进程通过ipcMain模块监听消息,也可通过mainWindow.webContents发送消息。
渲染进程则通过ipcRenderer模块进行通信。
下面演示主进程如何向渲染进程发送Cookie数据。
在main.js文件中添加相关代码。
const ipcMain = electron.ipcMain;
ipcMain.on('notice', (e, msg) => {
switch (msg) {
case 'getcodeCookie':
mainWindow.webContents.send('codeCookie',codeCookie)
break
default:
break
}
})
打开调试控制台,可以观察到消息输出。
在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');
});
// 监听 codeCookie
ipcRenderer.on('codeCookie', (e, msg) => {
codeCookie = msg;
console.log('接受主进程发送的codeCookie: '+codeCookie);
});
运行程序并点击登录按钮。
此时在调试控制台中可以看到接收到的codeCookie数据。

模拟登录实现
模拟登录
为了顺利操作后台,需要先完成登录并获取登录后的Cookie。
编辑index.js文件以处理登录逻辑。
const electron = require('electron');
const ipcRenderer = electron.ipcRenderer;
const path = require('path');
const superagent = require('superagent');
// 链接
const urls = {
loginUrl: "登录的地址",
codeUrl: "验证码地址",
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'
};
// 验证码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");
// 登录按钮 点击事件
btn_submit.addEventListener('click', (e) => {
ipcRenderer.send('notice', 'getcodeCookie');
// 获取输入文本
var name = input_name.value;
var pass = input_pass.value;
var code = input_check.value;
// 校验输入
if (name == "" || pass == "" || code == "") {
alert("请输入");
} else {
// 校验通过 开始进行登录操作
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)=>{
// 成功进入后台
console.log(res.text);
})
});
}
});
btn_refresh.addEventListener('click', (e) => {
});
ipcRenderer.on('codeCookie', (e, msg) => {
codeCookie = msg;
console.log('接受主进程发送的codeCookie: ' + codeCookie);
});
此处仅展示代码编写示例,实际获取Token或Cookie的过程可能因网站策略而异,需具体分析。
关键在于发起请求时必须携带正确的Cookie信息。
数据抓取与异步处理
数据抓取
成功登录后台后,即可开始抓取所需数据。这里使用cheerio库进行HTML解析。
cheerio https://cheerio.js.org/
cheerio可视为Node.js环境下的jQuery,其API与jQuery非常相似。
数据解析操作相对简单。
需要注意的是,Node.js是异步执行的,即使是for循环也是异步的,因此需小心处理异步逻辑。
若需等待多个请求完成后执行后续操作,应使用async/await语法。
数据导出功能
导出Excel表格
爬虫功能基本完成后,数据导出方式可根据需求灵活选择。
若需生成xls格式文件,可使用excel-export库,该库简单且满足基本需求。
此处推荐另一个更强大的库:better-xlsx。
下面演示如何调用系统保存对话框,将文件保存至本地。
编辑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);
});
运行程序,点击刷新验证码按钮后,即可看到系统标准的文件保存对话框。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。