用Electron写个带界面的nodejs爬虫的实现方法

什么是Electron

使用 JavaScript, HTML 和 CSS 构建跨平台的桌面应用

[官网](https://electronjs.org/)

实质就是一个精简的Webkit浏览器显示html页面,通过electron做中间层可以和系统交流。给web项目套上一个node环境的壳。

前言

公司买的推广居然没有后台的api,没有api又不想死板手动操作。那就做个爬虫吧。但是又是给小白用的,自然最好带个界面,本来用C#拖出来就好了,看到vs那么大,下载都要半天。干脆就用Electron做一个,顺便学习一下Electron。

准备工作

安装nodejs

npm安装electron(最好换成cnpm,不然可能失败)

hello world

官方提供了快速开始的手脚架,怎么方便怎么来。

https://github.com/atom/electron-quick-start

clone下来

git那些不是我们需要的,就删掉。

安装相关的依赖,推荐用yarn。

yarn https://yarn.bootcss.com/

cd 到 目录下

cnpm install yarn
yarn

等待依赖安装完成。

npm run start

顺利的话就可以看到程序启动。

界面编写

准备完毕,开始进入正题。

用vscode打开文件夹,顺带一提,vscode也是基于electron。vscode不愧是巨硬出品,越来越好用了。

整理一下

这里就不累赘了。

后台有多个小号要登录,就写个登录页面。

编辑一下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可以调用bootstap、jquery ,方便开发。调用jq有个小小的坑,注意一下。

不过我这里不需要什么效果,就简单点。

在vscode 快捷键 Ctrl + ` 调出 CMD 运行一下

npm run start

就可以看到我们刚刚写的网页了

下载验证码

登录是需要验证码的,我们把验证码下载下来。

流程是 请求验证码网站,下载验证码保存到本地显示,验证码的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
// 验证码的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 fs-extra模块是系统fs模块的扩展,提供了更多便利的 API,并继承了fs模块的 API。

主角就是 superagent https://www.npmjs.com/package/superagent

运行一下

很好,我们要的验证码和cookie 都有了。

分析登录流程

用 Fiddler 抓包工具和浏览器的调试控制台分析一下后台的登录。

这里不是重点就略过了。

Electron 通信

渲染进程(就是网页) 登录 需要 主进程保存的codeCookie ,这就要两者进行通信。

Electron之间的通信是用ipc

主进程的是 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);
});

这里只是演示一下代码怎么写,具体不一定那么顺利的拿到tokenCookie。具体情况具体分析。

关键是请求要带上cookie

数据抓取

成功进入到后台了,就要抓取需要的数据了。这里就需要 cheerio 工具了

cheerio https://cheerio.js.org/

可以理解是node上jq , 操作基本跟jq是一样的。

操作还是很简单的。

要注意的是nodejs是异步的,就连for也是异步的。

有时候要等待请求完成的话,就要用上 async 了。

导出xlsx表格

爬虫基本完成了,怎么导出数据就随意了。

如果是要生成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);
});

运行一下,点击刷新验证码按钮就可以看到熟悉的系统对话框

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 如何禁止网站内容被搜索引擎收录的几种方法讲解

    通常做网站的目标就是让搜索引擎收录,扩大推广面,但是如果你的网站涉及个人隐私或者机密性非公开的网页而需要禁止搜索引擎收录抓取的话,该如何操作呢?比如淘宝网就是禁止搜索引擎收录的一个例子,本文将教你几种做法来实现屏蔽或禁止搜索引擎收录抓取网站的内容. 搜索引擎蜘蛛不断爬行互联网,如果我们网站没有做出禁止搜索引擎收录的操作,很容易就会被搜索引擎收录.那么下面介绍一下怎么样禁止搜索引擎收录网站内容. 第一种.robots.txt方法 搜索引擎默认的遵守robots.txt协议(不排除某些耍流氓的引擎)

  • Nginx服务器屏蔽与禁止屏蔽网络爬虫的方法

    每个网站通常都会遇到很多非搜索引擎的爬虫,这些爬虫大部分都是用于内容采集或是初学者所写,它们和搜索引擎的爬虫不一样,没有频率控制,往往会消耗大量服务器资源,导致带宽白白浪费了. 其实Nginx可以非常容易地根据User-Agent过滤请求,我们只需要在需要URL入口位置通过一个简单的正则表达式就可以过滤不符合要求的爬虫请求: location / { if ($http_user_agent ~* "python|curl|java|wget|httpclient|okhttp") {

  • 浅谈Scrapy网络爬虫框架的工作原理和数据采集

    今天小编给大家详细的讲解一下Scrapy爬虫框架,希望对大家的学习有帮助. 1.Scrapy爬虫框架 Scrapy是一个使用Python编程语言编写的爬虫框架,任何人都可以根据自己的需求进行修改,并且使用起来非常的方便.它可以应用在数据采集.数据挖掘.网络异常用户检测.存储数据等方面. Scrapy使用了Twisted异步网络库来处理网络通讯.整体架构大致如下图所示. 2.由上图可知Scrapy爬虫框架主要由5个部分组成,分别是:Scrapy Engine(Scrapy引擎),Scheduler

  • Python常用爬虫代码总结方便查询

    beautifulsoup解析页面 from bs4 import BeautifulSoup soup = BeautifulSoup(htmltxt, "lxml") # 三种装载器 soup = BeautifulSoup("<a></p>", "html.parser") ### 只有起始标签的会自动补全,只有结束标签的会自动忽略 ### 结果为:<a></a> soup = Beautif

  • Python爬虫之UserAgent的使用实例

    问题: 在Python爬虫的过程中经常要模拟UserAgent, 因此自动生成UserAgent十分有用, 最近看到一个Python库(fake-useragent),可以随机生成各种UserAgent, 在这里记录一下, 留给自己爬虫使用. 安装 pip install fake-useragent 使用案例 基本使用 from fake_useragent import UserAgent ua = UserAgent() ua.ie # Mozilla/5.0 (Windows; U; M

  • Python爬虫beautifulsoup4常用的解析方法总结

    摘要 如何用beautifulsoup4解析各种情况的网页 beautifulsoup4的使用 关于beautifulsoup4,官网已经讲的很详细了,我这里就把一些常用的解析方法做个总结,方便查阅. 装载html文档 使用beautifulsoup的第一步是把html文档装载到beautifulsoup中,使其形成一个beautifulsoup对象. import requests from bs4 import BeautifulSoup url = "http://new.qq.com/o

  • 基于node.js实现爬虫的讲解

    1. cheerio 与 request request:模拟客户端行为,对页面进行请求 cheerio:对服务器端返回的页面进行解析: var cheerio = require('cheerio'); var request = require('request'); var startUrl = 'http://www.baidu.com' request(startUrl, function(err, response) { if (err) { console.log(err); }

  • Python3爬虫之自动查询天气并实现语音播报

    一.写在前面 之前写过一篇用Python发送天气预报邮件的博客,但是因为要手动输入城市名称,还要打开邮箱才能知道天气情况,这也太麻烦了.于是乎,有了这一篇博客,这次我要做的就是用Python获取本机IP地址,并根据这个IP地址获取物理位置也就是我所在的城市名称,然后用之前的办法实现查询天气,再利用百度语音得到天气预报的MP3文件,最后播放,这样是不是就很方(tou)便(lan)了呢? 二.具体步骤 这次有四个py文件:get_ip.py,get_wather.py,get_mp3.py和main

  • 通过python爬虫赚钱的方法

    (1)在校大学生.最好是数学或计算机相关专业,编程能力还可以的话,稍微看一下爬虫知识,主要涉及一门语言的爬虫库.html解析.内容存储等,复杂的还需要了解URL排重.模拟登录.验证码识别.多线程.代理.移动端抓取等.由于在校学生的工程经验比较少,建议找一些少量数据抓取的项目,而不要去接一些监控类的项目.或大规模抓取的项目.慢慢来,步子不要迈太大. (2)在职人员.如果你本身就是爬虫工程师,挣钱很简单.如果你不是,也不要紧.只要是做IT的,稍微学习一下爬虫应该不难.在职人员的优势是熟悉项目开发流程

  • Python 通过requests实现腾讯新闻抓取爬虫的方法

    最近也是学习了一些爬虫方面的知识.以我自己的理解,通常我们用浏览器查看网页时,是通过浏览器向服务器发送请求,然后服务器响应以后返回一些代码数据,再经过浏览器解析后呈现出来.而爬虫则是通过程序向服务器发送请求,并且将服务器返回的信息,通过一些处理后,就能得到我们想要的数据了. 以下是前段时间我用python写的一个爬取TX新闻标题及其网址的一个简单爬虫: 首先需要用到python中requests(方便全面的http请求库)和 BeautifulSoup(html解析库). 通过pip来安装这两个

随机推荐