端午节最后一天假花了一下午终于写出来一个自己的chrome扩展程序,六个小时在看开发文档,代码敲得也就几十行就实现了……
先谈背景,再谈搜集的资料,最后讲怎么实现。
背景是大家有算平均绩点和加权平均分的需要。绩点高于2.0才能拿学位证,高于1.0才有毕业证,出国申请学校都要用这个。加权平均分则用于每学年评奖学金的排名。
同学拿Python写了一个脚本,但是对于广大同学来说不方便使用,不可能人人都有Python环境,而且还用了第三方的库,更不能指望大家用pip指令安装库了吧。
那么写安卓程序怎么样呢?没意义,首先iPhone用户用不了,其次这玩意不像之前写的查宽带使用时长,这个一学期你也查不了几次啊。
在自己的服务器上搭建一个网站,然后微信公众号里面添加链接怎么样!好主意,但是我发现写网站太麻烦了,光配置LAMP环境都要折腾死了。
最后突然今天看到了一个推送讲怎么写chrome扩展,不得不承认那篇文章写的简直屎一般,让人完全没有想看的欲望。所以链接都不想贴给大家了。
既然决定写浏览器的扩展程序,那么就开始动手了。
首先先查一下chrome的扩展程序都是怎么写的。
主要是JavaScript和html。Html就不用说了随手写一个能用的就行,JavaScript还要先学一下,之前也就做CTF知道有这么个东西,从来都没用过,我们先看看有谁的教程最适合入门。
http://javascript.ruanyifeng.com/这个看了一下概述就看不下去,发现很适合完整的学习但是我用不上里面的几个功能。所以了解一下大致语法和标记一下一会可能用到的API就可以进行下一步了。
直接Google写chrome插件,看了两个别人入门用的极其简单的例子,发现了没什么用,还是应该看chrome的开发文档。全英文,很蛋疼,怎么办呢,搜一下知乎上有人推荐360给翻译的文档http://open.chrome.360.cn/extension_dev/devguide.html。感谢360。(后来发现有点老了,但是对这个简单的插件完全够用了)
在了解了大概所有的插件的实现方式之后,我就知道要怎么做了。
两个方案,XMLHttpRequest,在用户登录之后拿cookies去请求数据。这个想想就麻烦,而且都有浏览器了干嘛不直接让浏览器访问好我们在处理呢。方案二是直接用js处理页面上的elements,怎么简单怎么来,所以就决定用这个了。
查看页面元素,发现是个table,那就查怎么处理table,一下子就找到目标了。
http://blog.csdn.net/itmyhome1990/article/details/7005784
试验一下,
var el=document.getElementById("Datagrid1").rows[1].cells[4].innerHTML;
alert(el);
效果图
完美,记下来要用的,列里面5能判断是不是公选,7是学分,8是绩点,13是成绩。(程序从0开始数)
但是按这个写了JavaScript后怎么显示找不到对象呢?
还好我机智找来了写Python脚本的同学问了下!
神特么里面嵌套frame框架。查了好久在发现问题,这个大家要注意了!
http://www.cnblogs.com/rainman/archive/2011/02/16/1956431.html#m1
知道了怎么操作frame框架。
找到框架id="iframeautoheight"
还学会了如何调试JavaScript,直接在chrome中就可以打断点
http://wiki.jikexueyuan.com/project/chrome-devtools/debugging-javascript.html
讲真,第一次拿浏览器当IDE调试程序,发现JavaScript真方便…
说真的我们已经完成了全部的内容了,最后把代码全都写出来就30来行。。。var doc= document.getElementById('iframeautoheight').contentDocument;
var tb=doc.getElementById('Datagrid1');
var Credit=0;//学分
var GPA=0;//绩点
var Grade=0;//成绩
var type;
var sumCredit=0;
var sumGPA=0;
var sumMul=0;
var sumGrade=0;
for (var i=1;i<tb.rows.length;i++){
Credit=parseFloat(tb.rows[i].cells[6].innerHTML);
GPA=parseFloat(tb.rows[i].cells[7].innerHTML);
type=tb.rows[i].cells[5].innerHTML;
if(type===' '){//若不是这个,说明是通识选修课,不计入
sumGPA=sumGPA+GPA;
sumMul=sumMul+(Credit*GPA);
type=tb.rows[i].cells[12].innerHTML;
if(!isNaN(parseFloat(type))){//如果是认知实习成绩为良好,则不计入,良好的parseInt结果为NaN
Grade=parseFloat(type);
sumCredit=sumCredit+Credit;
sumGrade=sumGrade+(Grade*Credit);
}
}
}
var avg=sumMul/sumCredit;
var avg1=sumGrade/sumCredit;
avg = avg.toFixed(3);//保留三位小数
avg1=avg1.toFixed(3);
var s="您的平均GPA为"+avg+'\n 加权平均分为'+avg1;
alert(s);
而且大家要用的话完全只拿这个代码就可以了,真的,弄到最后发现完全没有打包成chrome扩展程序的必要,而且就算打包成.crx,在国内大家也都是用的搜狗360腾讯,根本安装不上扩展。
下面是正确用法!
所以各位同学请将上面的JavaScript代码复制,然后进到你的教务系统,
如果查询到目前为止的所有成绩
等页面加载完,按F12调出开发者工具,在console(命令行)里面粘贴上面的JavaScript代码,回车,就会像这样
如果需要查某学期或者某学年,选择好学期或者学年后单击 按学期查询。
等页面加载完之后执行步骤和上面一样。
注:平均绩点算法(Σ学分*绩点)/(Σ学分)
加权平均分(Σ学分*期末成绩)/(Σ学分)
两个均未计入公选课成绩,且加权平均分没有计算认知实习,因为期末成绩评定是良好。
接下来是重头戏,就是我查了六个小时文档的扯淡玩意……
怎么建立一个扩展程序。
第一步新建一个文件夹,命名为你扩展程序的名字。
第二步在里面新建一些文件,具体可参考谷歌的文档
比如我的总共就这些
接下来讲一讲每个是干嘛的,以及怎么连接js脚本的(我查文档就是为了实现这个!)
manifest.json是必须要有的,具体属性自己查文档。
{
"name": "GPAcal",
"version": "0.1.0",
"manifest_version": 2,
"description": "Management your grade and calculateGPA",
"permissions": [
"tabs",
"http://*.cumt.edu.cn/*",
"http://202.119.206.61/*"
],
"browser_action": {
"default_icon": "icon.png" ,
"default_title": "GPAcal",
"default_popup": "popup.html"
}
}
popup.html
是你点开浏览器状态栏的按钮后弹出来的那个小页面的html,真正的大坑在这个地方。
我放一下我最开始最简洁的html
<html>
<head>
<title>绩点计算</title>
<scriptsrc="popup.js"></script>
</head>
<body>
<p>等待页面加载完成</p>
<p>单击下面按钮</p>
<form>
<input type="button"value="点我!"id="bn">
</form>
</body>
</html>
注意我查了好久文档才解决的问题,你不能在html里面写script,会被谷歌禁用
使用教程,http://open.chrome.360.cn/extension_dev/contentSecurityPolicy.html
请大家认真观看!
请大家认真观看!
请大家认真观看!
我就在这里浪费了很多时间。
你不能在button中直接指定onclick="run()",会因为Content Security Policy (CSP)策略禁止执行。
正确的做法是像我上面那样写,然后再写popup.js(多读读官方给的文档就理解什么意思了,我还是看了官方给的其他的demo才明白到底要怎么调用脚本。)
function run(){
chrome.tabs.executeScript(null,{file: "GPAcal.js"})//调用脚本
}
document.addEventListener('DOMContentLoaded',function () {
var bn=document.getElementById('bn');
bn.addEventListener('click', run);
});//官方规定必须这么写,不能在html里直接写onclick,这段目的是等DOM加载完后执行脚本找到按钮绑定监听器。官方文档意思和这个一样,只是匹配element的方法不同。
最终你就可以在扩展工具里面打包,拖进浏览器安装了。
写到这里就差不多,反正给大家的建议就是认真看文档,我的问题都是因为不符合文档上写的东西才造成的。
希望大家能从中收获一些东西。