本文主要拆解一个Chrome浏览器插件,包括功能解析、思路分析以及源码解析。其主要功能是下载超星平台里面课程考试的题目,最后导出Excel表格。
1、插件功能演示
插件加载后的界面:
图1 插件加载后的界面
打开超星平台里面的某个课程的考试,点击右上角插件图标,左下角就会显示下载Excel表格的任务:
图2 点击下载后导出为Excel文件
打开下载后的文件,则考试题目与答案和答案详情都导出在Excel文件里面。
图3 Excel表格内容
2、思路分析:
根据图3的Excel表格内容,需要提取并导出的信息主要包括题目内容、答案与答案内容。首先采用Chrome的开发者工具来查看网页,定位上述信息。
图4 网页元素中包含的信息
如图4所示,每一题题目的所有信息(包括答案,答案详情)都位于类”TiMu”标签下,题目详情是位于类”TiMu”下的类”Cy_Title”中,而答案详情是位于类”TiMu”下的类”Cy_ulTop”下,答案位于类”TiMu”下的类”Py_answer”中。要解决的主要问题:
如何利用javascript脚本将信息上述标签中提取出来;
提出到信息如何导出到Excel文件;
第1个问题要借助于jQuery库的选择器来实现,第2个问题除了使用jQuery库,还需要js-xlsx库。
3、插件源代码分析:
插件的图标包含在image文件夹中,使用到的javascript脚本主要在js文件夹中,包括cs.js、backgroud.js、jquery.min.js(对应jQuery库)和xlsx.core.min(对应js-xlsx库)。本文不深入后面的两个js脚本库文件,所以重点就落在cs.js和background.js。
图5 插件源代码结构
首先来看background.js脚本的内容。其中chrome.browserAction.onClicked.addListener表示设置一个监听事件,onClicked表示点击,browserAction表示右上角图标,当点击右上角图标时,则执行chrome.tabs中的executeScript函数,该函数向页面注入三个js文件(其中需要的权限在manifest.json文件的”permissions”声明”tabs”),三个js文件中的jquery.min.js和xlsx.core.min.js为库文件(包含一些功能,为后面将数据导出Excel文件提供一些方法,可在网上下载得到)。cs.js使用两个库文件提供的方法来解决”思路分析”中提到的两个问题,即从网页中提取信息和导出保存到Excel文件。
1 | chrome.browserAction.onClicked.addListener( function(el) { |
步骤1 从网页提取信息
cs.js脚本中通过$(“.TiMu”).each(index, el)可以获得所有题目的div,存储在el(element)中,其中each相当于一个for循环,每次把一个题目的相关信息存储在el中;
1 | $(".TiMu").each((index, el) => { //获取里面的每个题目,相当于for,一次获取每一个符合TiMu的对象 |
通过语句el.querySelector(“.Cy_Title>div”).innerText获得题目内容,其中querySelector获取当前题目的div,而innerText提取其中的文本信息,赋值给title。语句el.querySelector(“.Pu_answer>span”).innerText获得正确答案内容,先使用条件语句el.querySelector(“.Py_answer>span”))!=null)判断答案内容的存在性,如果存在,则将答案信息赋值给answer变量。
获得题目内容和答案后,对照图3的Excel表格内容,即现在已经获取前两列的内容,还需要的是第3列,即符合答案的选项内容详情,该功能通过getAnswerDesc()方法来实现。getAnswerDesc方法以answer变量为参数,通过匹配’A’,’B’,’C’,’D’,’E’,’F’,’G’字符将索引记录在数值ret中。例如,当答案answer中有’A’字符,则将”0”记入在数组ret中,如果答案answer为”ABD”,则将”013”记录到ret中,这个索引序列数组用于索引出对应答案选项内容,具体用于索引答案详情的类名为”Cy_ulTop”中有标签”li”的选项。索引序列数组的对应的第几个”li”标签,例如索引序列数组ret为”013”时,则对应的是第1个,第2个和第4个”li”标签。对应的代码如下:
1 | for (let i = 0; i < answerDescArray.length; i++) {//对应的数字索引序列一个一个的匹配上方的答案内容 |
获得答案的选项内容详情后,再将三个信息压入到二维数组:
1 | dataList.push([//将数组[title, answer, answerDesc]压入二维数组中 |
如果answer答案中不包含’A’~’G’的字符,则可判断当前题目为判断题(答案为’√’或者是’×’),则进入else分支代码,代码逻辑与if分支相同,只不过答案内容只有”对”和”错”两个,代码如下:
1 | if (el.querySelector(".Py_answer>span>i").innerText == "√") {//匹配到√ |
通过上述的步骤,完成题目内容、答案和答案选项内容详情等三部分信息的提取,接下来就是信息导出并保存到Excel文档。
步骤2 将信息导出保存到Excel文件
步骤1中获得题目信息等对应的二维数组,剩下的事情就是将二维数组导出到Excel文件。主要通过如下的三个方法:
1 | function sheet2blob(sheet, sheetName) |
三个函数调用jQuery库和js-xlsx库中的相关方法来实现功能。exportSpecialExcel函数的参数aoa是二维数组,并且该函数要调用sheet2blob和openDownloadDialog两个函数。如何利用js-xlsx库将二维数组导出Excel表格,可参考文献2,此处不再赘述。
4、参考文献:
- 关于chrome.tabs的相关说明文档:
http://www.kkh86.com/it/chrome-extension-doc/extensions/tabs.html#method-executeScript
2)https://www.cnblogs.com/liuxianan/p/js-excel.html
附录:
本文演示的插件源码下载地址如下:
https://github.com/tfzhang55/mooc2excel