前情提要:

  1. electron从零开始做个倒计时
  2. 用electron做一个浏览器

源码:定制专属CSDN App

iframe也好,webview也罢,都是直接嵌入网页,几乎不存在对网页定制的可能,而且很多网站是禁止被插入别人的网页的。

所以,若想重新规划某个网站的网页,并写在自己的App中,那就只能用爬虫了。

node爬虫

爬虫操作需要两个额外的包:requestcheerio,前者请求目标链接,后者分析dom元素。

npm install request --save
npm install cheerio --save

如今node做得越来越智能了,其命令行提供的补全功能可以减少三分之一的工作量。进入node后先导入三个包

var https = require("https")
var cheerio = require("cheerio");

然后先尝试一下获取网页的源文件

var url="https://tinycool.blog.csdn.net/"; //网址

var html="";
https.get(url,function(res){
    res.on("data",function(chunk){
        html+=chunk;
    })
    res.on("end",function(){
        console.log(html);  //当遇到'end'事件
    });
})

至此就可以看到整个html的页面都被打印出来了,接下来则是cheerio的秀态姆,来解析这个html,从而对打印的内容进行定制,例如只是想得到每篇博客的预览。

在Edge浏览器中按下F12可进入开发者模式,查看网页元素,其中所有博客内容都被放在一个article中。

在这里插入图片描述

所以接下来可用cheerio查询所有的article

var dom = cheerio.load(html);
var a = dom("article");
a.text()

就可以看到文章的标题了。

新建electron应用

在熟悉js爬虫的原理之后,就可以做一个electron的应用了。首先,新建一个文件夹,用于存放项目,并通过npm进行初始化。

>mkdir csdnClawer
>cd csdnClawer
csdnClawer>npm init

接下来,npm在初始化时会问一些问题,其中项目名称不得有大写字母,最好将entry point改为main.js,其他内容没有什么需要注意的,最后得到的package.json大致为

{
  "name": "csdn_clawer",
  "version": "1.0.0",
  "description": "my own csdn",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "tinycool",
  "license": "ISC"
}

然后,安装必要的包

\csdnClawer>npm install --save-dev electron
\csdnClawer>npm install --save-dev request
\csdnClawer>npm install --save-dev cheerio

然后修改配置文件package.json,在script字段下新增一条命令,注意如果有多条命令的话,彼此之间用,分开。

{
  "scripts": {
    "start": "electron ."
  }
}

这样就可以用npm start来打开electron项目了。

稳妥起见,先按照官方的指示,做一个hello world测试界面。根据刚刚的设置,新建一个main.js文件作为入口文件,内容如下

const { app, BrowserWindow } = require('electron')
const {path} = require('path')

function createWindow (){
  const win = new BrowserWindow({
    width: 800,
    height: 300
  })
  //加载index.html
  win.loadFile('index.html')
}

app.whenReady().then(()=>{
  createWindow()
	app.on("activate", function(){
		if(BrowserWindow.getAllWindows().length == 0)
			createWindow()
	})
})

app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') 
		app.quit()
})

然后写一下index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>mini csdn</title>
  </head>
  <body>
    <div id="title">my articles<div>
  </body>
</html>

最后,在命令行中输入npm start,就可以看到一个质朴的hello world窗口了。

定制CSDN

先修改index.html,将body中的div清空,然后修改main.js中的win,添加一下preload成员,即

const mainWindow = new BrowserWindow({
  width: 800,
  height: 600,
  webPreferences: {
    preload: path.join(__dirname, 'preload.js')
  }
})

接下来新建preload.js文件,添加内容

const https = require("https")
const cheerio = require("cheerio")
window.addEventListener('DOMContentLoaded', () => {
  var url="https://tinycool.blog.csdn.net/?type=blog";
  var html="";
  https.get(url,function(res){
      res.on("data",function(chunk){
          html+=chunk;
      })
      res.on("end",function(){
        insertDiv(html);
      });
  })
})

function insertDiv(html){
  var dom = cheerio.load(html);
  var a = dom("article");
  var div = document.createElement("div");
  div.innerHTML = a.html(); //将字符串转为div
  document.getElementById("title").appendChild(div);
}

在这里插入图片描述

可见,貌似只得到了第一篇博客的div

这是因为,尽管博客中有多个article,而dom('article')也的确返回了所有article,但在调用html()时,只输出了第一个,为了获取所有的article,可通过.eq来逐个调用,故将insertDiv改为

function insertDiv(html){
  var dom = cheerio.load(html);
  var articles = dom("article");
  var div = document.createElement("div");
  for(i=0; i<articles.length; i++){
    div.innerHTML += articles.eq(i).html(); //将字符串转为div
  }
  document.getElementById("title").appendChild(div);
}

这回倒是得到了许多个article,但光秃秃的太难看了,所以接下来要把CSND的css偷出来😜

在这里插入图片描述

新建style.css,并在htmltitle前添加<link href="./style.css" rel="stylesheet">

由于这些css实在太多,所以只列出blog-list-content,其他内容可以自行查找,或者干脆根据class重新定义

.blog-list-content{
    color: #555666;
    margin-top: 8px;
    line-height: 24px;
    overflow: hidden;
    white-space: normal;
    word-break: break-word;
}

其效果为

在这里插入图片描述

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐