用 electron 实现第三方网页客户端
- 作者:Bougie
- 创建于:2020-02-10
- 更新于:2023-03-09
# 为什么要做第三方客户端
- 首先是为了获得更好的用户体验。如下图所示,左侧是第三方微博客户端 Share,右侧是 V2EX 第三方客户端。两者的特点都是界面都很简洁,功能比较纯粹。早期也有很多第三方贴吧 APP、视频软件 APP,但是随着大厂流量战争越打越强,就对这些第三方 APP 进行了封杀。
- 其次我们可以在第三方客户端中加入广告和捐赠功能,来获得一部分额外收入。🍭
- 最后就是在有一定用户量后开源出来可以吸一波 Star。不过这个和上面有点矛盾,因为开源出来后你加入的广告就可能被别人去掉后重新编译打包了。甚至里面的捐赠支付二维码会被改成其他人的二维码。这一点就看个人取舍了。
# 从哪些方面优化第三方客户端体验
- 使客户端功能更纯粹。现在无论什么 APP 都要加新闻、直播、钱包、小视频的功能(说的就是微信、百度、微博这些毒瘤 😡)。我们封装第三方客户端时首当其冲就是要去掉这些无用功能。
- 去除广告。幸运破解器也可以帮助去除,不过成功率较低。
- 使用贴合原生系统的设计风格。安卓使用 material design,苹果使用 cupertino 设计风格(这个名子来自 flutter,官方没有具体名子)。
- 动画贴近原生。使用系统级的过渡动画,这样会使 APP 界面切换更流畅。如何检测动画是否是系统级的?在开发者选项中将动画速度切换成 0.5 倍,如果 APP 的动画速度也变慢了,说明动画是系统级的。在 flutter 中,由于控件都是使用 Skia 绘制的,而非原生控件,动画引擎也是内建的,所以无法使用系统内建动画,跟系统有一股割裂感。这也是我不喜欢 flutter 的一点。
- 增加特色功能。如主题换肤、特殊权限破解(如看视频免 vip 等等,但是随着这些鉴权逐渐迁往服务端,现在基本不可能实现了,只能想办法找一些漏洞)。
# 用 Electron 实现第三方网页客户端
Electron 本身便是一个浏览器,在实现第三方网页客户端上有天然优势。传统方法抓取网页 api 的方式是尽可能的模拟请求头,但是在 electron 中我们可以用 webview 访问这个网页,然后将 webview 中的请求到的接口抓取过来。这样本质和直接访问原网页没有任何不同,但是我们可以在抓到接口后对页面进行自定义,添加更多自定义功能。
# 首先要创建一个隐藏的网页
electron 里面据我所知的有两种方法。
通过
BrowserWindow
主进程中创建
设置BrowserWindow
的 show 属性为false
,此时 window 示例在主进程中,渲染进程想要获取数据需要通过 ipc 和主进程通信。这样做的的好处是在主进程中能更方便的进行更高权限的操作。在渲染进程中直接通过
webview
创建
创建一个隐藏的webview
去访问相关网页地址。好处非常明显,获取数据不用和主进程通信,操作基本在渲染进程完成。
# 抓取隐藏网页中的接口
使用 debgguer 工具获取网页中请求的接口。这个 degguer 和 chrome 中的非常相似,不过是没有界面的。
const { BrowserWindow } = require('electron')
let win = new BrowserWindow({ show: false })
try {
win.webContents.debugger.attach('1.1')
} catch (err) {
console.log('Debugger attach failed : ', err)
}
win.webContents.debugger.on('detach', (event, reason) => {
console.log('Debugger detached due to : ', reason)
})
win.webContents.debugger.on('message', (event, method, params) => {
if (method === 'Network.requestWillBeSent') {
if (params.request.url === 'https://www.github.com') {
win.webContents.debugger.detach()
}
}
})
win.webContents.debugger.sendCommand('Network.enable')
只有运行 attach 方法后,接口才会被捕捉到,类似 chrome 中不开启开发者工具就不会捕捉请求。抓取到想要的数据后需要运行 detach 方法,不然内存会爆表。
# 抓取隐藏网页中的 html 内容
使用 executeJavaScript
方法获取 dom 元素,在页面加载完成后执行。
win.webContents.on('did-finish-load', () => {
const code = 'document.getElementById("username").innerHTML'
win.webContents
.executeJavaScript(code, true)
.then(username => console.log(username))
)}
有以上两个方法肯定能够很轻松的制作出网页第三方客户端,如果有时间和精力的话 🤟