Electron+Vue使用Nodejs开发爬虫

相关库

1
npm install request cheerio async -save

其中

cheerio 抓取HTML

https://github.com/cheeriojs/cheerio

cheerio

安装

1
npm install cheerio

使用

1
2
3
4
5
6
7
const cheerio = require('cheerio');
const $ = cheerio.load('<h2 class="title">Hello world</h2>');

$('h2.title').text('Hello there!');
$('h2').addClass('welcome');

$.html();

查找

1
2
3
4
$('#fruits').find('li').length
//=> 3
$('#fruits').find($('.apple')).length
//=> 1

Axios/Request

Axios

基于 Promise 的 HTTP 客户端,可用于浏览器和 Node.js

Axios 是一个基于 Promise 的 HTTP 库,可用在 Node.js 和浏览器上发起 HTTP 请求,支持所有现代浏览器,甚至包括 IE8+!

优点

  • 同时支持 Node.js 和浏览器
  • 支持 Promise API
  • 可以配置或取消请求
  • 可以设置响应超时
  • 支持防止跨站点请求伪造(XSRF)攻击
  • 可以拦截未执行的请求或响应
  • 支持显示上传进度
  • 广泛用于 React 和 Vue 项目

缺点

  • 用起来比较麻烦

Request

简化版 HTTP 请求客户端

Request 提供了一种简化的 HTTP 请求方式。 你可以使用比其他 HTTP 库更少的代码来发起 HTTP 请求。 它不是基于 Promise 的,但如果你需要 Promise,你可以引入request-promise 库,将请求封装为 Promise 并返回。

优点

  • API 简单易用

缺点

  • 不基于 Promise

request库

1
2
3
4
5
6
7
8
9
var request = require('request');

// 通过 GET 请求来读取 http://cnodejs.org/ 的内容
request('http://cnodejs.org/', function (error, response, body) {
if (!error && response.statusCode == 200) {
// 输出网页内容
console.log(body);
}
});

请求跨域的解决方式

1
2
3
4
5
6
7
8
9
10
11
// Create the browser window.
const win = new BrowserWindow({
width: 1200,
height: 800,
webPreferences: {
webSecurity: false,
nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION
}
});

app.commandLine.appendSwitch("disable-features", "OutOfBlinkCors");

主要添加了第6行和第11行,正式运行时删除即可

文件夹路径

主进程

1
2
const { app } = require('electron')
app.getPath(name)

渲染进程

1
const { app } = window.require("electron").remote;

String - You can request the following paths by the name:

  • home 用户的 home 文件夹(主目录)

  • appData

    Per-user application data directory, which by default points to:

    • %APPDATA% Windows 中
    • $XDG_CONFIG_HOME or ~/.config Linux 中
    • ~/Library/Application Support macOS 中
  • userData 储存你应用程序设置文件的文件夹,默认是 appData 文件夹附加应用的名称

  • temp 临时文件夹

  • exe当前的可执行文件

  • module The libchromiumcontent

  • desktop 当前用户的桌面文件夹

  • documents 用户文档目录的路径

  • downloads 用户下载目录的路径

  • music 用户音乐目录的路径

  • pictures 用户图片目录的路径

  • videos 用户视频目录的路径

  • recent Directory for the user’s recent files (Windows only).

  • logs应用程序的日志文件夹

  • pepperFlashSystemPlugin Pepper Flash 插件的系统版本的完成路径。

  • crashDumps Directory where crash dumps are stored.

Returns String - A path to a special directory or file associated with name. On failure, an Error is thrown.

If app.getPath('logs') is called without called app.setAppLogsPath() being called first, a default log directory will be created equivalent to calling app.setAppLogsPath() without a path parameter.

选择文件夹

添加引用

1
const { app, dialog } = window.require("electron").remote;

弹窗选择

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
select_dir: function() {
var that = this;
dialog
.showOpenDialog({
properties: ["openFile", "openDirectory"]
})
.then(result => {
if (!result.canceled) {
that.outpath = result.filePaths[0];
}
})
.catch(err => {
console.log(err);
});
}

文件下载

引用

1
2
const request = require("request");
var fs = window.require("fs");

下载

1
2
3
4
5
6
7
8
9
10
11
var fileurl = "http://www.psvmc.cn/favicon.ico";
let filename = fileurl.split("/").reverse()[0];
let filepath = this.outpath + "\\" + filename;
let stream = fs.createWriteStream(filepath);
request(fileurl)
.pipe(stream)
.on("close", function(error) {
if (!error) {
console.log("文件[" + filename + "]下载完毕");
}
});

文件上传

electron写应用时,会遇到自动上传的需求。但是H5中只能通过input(type=file)来手动上传,JS又没有读取文件的权限,此时,我们可以借助node模块完成需求。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
uploadfile: function() {
var filename = "favicon.ico";
let filepath = this.outpath + "\\" + filename;
fs.readFile(filepath, (err, data) => {
if (!err) {
let file = new File([data], filename, {
type: "image/" + filename.split(".").reverse()[0]
});
let form = new FormData();
form.append("file", file);
form.append("savefolder", "resourcetest");
form.append("iscover", 0);
form.append("isrename", 0);
let request_url = "http://file.psvmc.com/up/upfile";
let xhr = new XMLHttpRequest();
xhr.open("post", request_url);
xhr.send(form);
xhr.onload = function() {
console.info(this.responseText);
};
}
});
}

调用接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var request = require('request');
var url="请求url";
var loginname = this.$refs["loginname"].value;
var loginpwd = this.$refs["loginpwd"].value;
var requestData = {
loginname: loginname,
loginpwd: loginpwd
}
request({
url: url,
method: "POST",
json: true,
headers: {
"content-type": "application/json",
},
body: requestData
}, function(error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body) // 请求成功的处理逻辑
}
});

按行读取文本文件

添加引用

1
2
const fs = window.require("fs");
var readline = window.require("readline");

方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{
readFileToArr(fReadName, callback) {
var fRead = fs.createReadStream(fReadName);
var objReadline = readline.createInterface({
input: fRead
});
var arr = new Array();
objReadline.on("line", function(line) {
arr.push(line);
});
objReadline.on("close", function() {
callback(arr);
});
},
readfile() {
this.readFileToArr("public/wordlist.txt", function(arr) {
var arr_new = [];
arr.forEach((item) => {
var item_arr = item.split(" ");
if (item_arr.length > 0 && item_arr[1]) {
arr_new.push(item_arr[0]);
}
});
console.info(arr_new);
});
}
}