--inspect
参数是调试参数,启动调试后在Chrome浏览器中打开
chrome://inspect
点击
Open dedicated DevTools for Node
即可打断点观察程序运行。
2.添加Electron主进程入口脚本
作为一个Electron项目,还应至少具有主进程入口
main.js
。
这里直接贴出成品,读者请看后文。
//main.js
const {app, BrowserWindow} = require('electron')
const fs = require('fs')
let mainWindow
function createWindow() {
mainWindow = new BrowserWindow({
width: 350,
height: 600
mainWindow.webContents.userAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1"
mainWindow.loadURL("https://m.huya.com/688")
mainWindow.webContents.openDevTools({
mode: "undocked"
const js = fs.readFileSync('inject.js').toString()
mainWindow.webContents.executeJavaScript(js)
app.on("ready", createWindow)
复制代码
其中援引一段注入代码
inject.js
:
console.log("INJECT SUCCESS!");
const tanmu = document.getElementById("tanmuScroll");
tanmu.addEventListener("DOMNodeInserted", function (e) {
console.log(e.target.innerText)
复制代码
至此,你的项目应具有以下文件结构:
├── inject.js
├── LICENSE.md
├── main.js
├── node_modules
├──
package
.json
├──
package
-lock.json
└── README.md
复制代码
三、代码解释
代码很简短,我想懂点英语的话看懂不难。
其流程首先是导入相关模块,app控制electron生命周期,BrowserWindow是创建窗口的类,fs是读写模块。
然后创建createWindow回调函数,当app发出ready事件,也即electron准备好时立即执行该函数。
在该函数中向控制台注入一段js代码,将直播间的聊天信息写入控制台。
最后将app的ready事件与createWindow函数绑定。
期间,我遇到了不少
从入门到劝退
的问题,记录如下:
1.网络慢,electron下载不来,下到一半程序中断出错
尽管淘宝提供
electron镜像
,但是我怎么也没有设置成功,我感觉可能是淘宝镜像更新不及时的BUG?并不清楚,反正我没有成功,如果你成功了请留言告知。
(我在这里安利了一个某2ray的壳子,说我违规。。所以我删掉了。)
并且,我在.bashrc中添加了以下别名,使用比较方便。
alias upxy='export http_proxy=http://127.0.0.1:8000 && export https_proxy=http://127.0.0.1:8000'
复制代码
另外,好像直接从electron的
releases
下载解压到node_modules也行?我没有试。
2.调试Electron
我一开始使用了WebStorm作为IDE,它很方便,提供了比较强大的提示和代码格式化功能,但我并不知道如何调试Electron程序,于是我只能猜各个对象有什么方法,可是我怎么能猜中我需要的方法起了什么鬼名字呢。。
经查阅
Electron官方文档
(尽管它是中文,但是在没有代理的情况下有些图片加载不出来,而你不知道),得知
--inspect
是调试参数,正如上文那样可以将它加入调试入口并在你的项目文件夹中执行:
npm run debug 或 yarn debug
复制代码
启动调试后在Chrome浏览器中打开
chrome://inspect
点击
Open dedicated DevTools for Node
即可。
可以看到我其实是手动执行了额外的命令进行调试,这似乎是可以集成到WebStorm中,不过需要额外的配置,我没有试。
3.DOMNodeInserted事件
该事件在当选定元素的子DOM树被改变时触发。
我考虑了很久怎么才能从JS黑箱子(js被uglify)中抽出直播间的聊天信息,一开始我的办法是使用Chrome开发工具的Override重写功能,或者Charles代理,替换了js的内容,由js直接打印,但是这样不能写入Electron代码。我找了很久也没有找到怎么才能在网页载入的时候给js打补丁的方法,如果你找到了请留言告知。
另外我也没有找到html事件的详细文档在哪里?只是在百度上搜索的时候偶然得知有这么一个事件。不知道还有什么其它很好用的事件存在。
4.JavaScript断点调试
虽然本例中并未遇到网页内JS调试问题,但是这是我曾考虑过的问题
经研究JS代码,发现只要在任意网址后加
?log
即可开启虎牙直播间的调试模式,我也忘了怎么发现的了,反正看了半天,真是头秃。。
点击上图
room_taf_iscroll_xxxxxxx.js
即可跳转到源码页。
可以看到,代码被压缩(并且混淆与加密)了,据说可以用一个叫作map的文件恢复,然而我并没有。不过我们可以把它展开成顺眼的格式化代码,只需要点击窗口下面的花括号。
那么,只需要点击代码前面的行号就可以添加断点了,可以看到断点行已经变成了靓丽的基佬紫。
需要注意的是,格式化代码会在新的标签中弹出,而它并不能被修改,而原来凌乱的代码是可以被修改的,办法是把整洁的代码copy过去就可以了。另外,如果你指定了Override文件夹,那么你一旦对原文件做出修改他会被记录下来,并在以后一直使用。
5.其他提示
如果直播间没有直播,该代码会出错,你应该指定一个正在直播的直播间。
我刚才想到了什么要写,但是现在想不起来了。
我想起来了,在PC端打开移动版页面是不能播放直播间视频的,猜测可能是移动版调用了手机的硬件解码接口?而PC没有这个接口,压根不能播放所以我也没有在代码中去掉播放器。
然后,PC版页面直接在DOM树中删除播放器的容器元素后,虽然不出声了,但是我观察资源管理器发现网页还在下载直播视频流,速度有1Mb/s左右,不知道怎么才能让他彻底停止,而只保留聊天信息。
可以看到,聊天内容是直接打印在渲染进程的控制台上的,这一点可以用Electron的主进程与渲染进程的ipc通信接口来改进,比如可以由主进程收集并写入本地文件。
最后,我其实,一开始只是想稍微记录一下,怎么写出这么多字。。
撒花撒花~