使用脚本一键统计青年大学习的情况-附免费代码

大熙哥 2021年07月14日 397次浏览

非专业人士请切换到“如何使用”的章节,直接教你使用

前言

因为一周一次的青年大学习是需要进行统计并上传的,每次学习的人数未知、姓名顺序又可能打乱,如果人肉进行排查将会十分耗时耗力,特别是这种重复性工作做多了两个星期就很烦躁,因此开发了这个油猴脚本,只需要安装好,打开对应的页面就会弹出学习情况并可一键复制进行上报。
image.png

研发步骤

使用开发者工具分析

我们在青年大学习页面按下F12或者右键点击检查弹出开发者工具,点击开发者工具的选项卡中的网络,切换到网络请求的列表视图。

16262749701.png

此时网络视图已经是清空状态,我们可以刷新页面,网络视频便会把与后端交互的请求一个个都原形毕露。

image.png

寻找已学名单的列表

首先需要确定我们要找什么,就是要找已学名单的列表,所以我们主要是找关键词 list,我们点击列表中的list请求,查看返回数据。

16262753511.png

找到了请求就事半功倍了,我们对这个请求点击右键,复制fetch请求。

image.png

分析具体请求的参数和头部

我们来康康这个fetch请求具体是什么内容。

fetch("https://youthstudy.12355.net/apibackend/admin/young/organize/userList?organizedId=组织id&pageNo=页码", {
  "headers": {
    "accept": "application/json, text/plain, */*",
    "accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
    "cache-control": "no-cache",
    "pragma": "no-cache",
    "sec-ch-ua": "\"Chromium\";v=\"92\", \" Not A;Brand\";v=\"99\", \"Microsoft Edge\";v=\"92\"",
    "sec-ch-ua-mobile": "?0",
    "sec-fetch-dest": "empty",
    "sec-fetch-mode": "cors",
    "sec-fetch-site": "same-origin",
    "x-litemall-admin-token": "登录凭证(token)",
    "x-litemall-identification": "young"
  },
  "referrer": "https://youthstudy.12355.net/backend/",
  "referrerPolicy": "strict-origin-when-cross-origin",
  "body": null,
  "method": "GET",
  "mode": "cors",
  "credentials": "include"
});

我把我的敏感信息去除替换成中文,对应你复制到的内容则是已经自动填好的,显然,在以上fetch请求中,所需参数是组织id和页码,在请求头需要放入token便可以获取到已学名单。

小试牛刀,在控制台执行fetch请求

偷偷告诉你,刚刚生成的fetch请求直接粘贴到控制台运行是没有任何数据的哦!原因是该fetch请求没有写打印输出的语句。怎么写呢?这里我将教最简单的方法,当然如果你是大佬使用同步的方式实现那是更好了。

办法就是在fetch后面加个then,并打印返回回来的数据即可。

更多知识点:
fetch请求是什么?怎么用
fetch 同步异步

fetch("https://youthstudy.12355.net/apibackend/admin/young/organize/userList?organizedId=组织id&pageNo=页码", {
  "headers": {
    "accept": "application/json, text/plain, */*",
    "accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
    "cache-control": "no-cache",
    "pragma": "no-cache",
    "sec-ch-ua": "\"Chromium\";v=\"92\", \" Not A;Brand\";v=\"99\", \"Microsoft Edge\";v=\"92\"",
    "sec-ch-ua-mobile": "?0",
    "sec-fetch-dest": "empty",
    "sec-fetch-mode": "cors",
    "sec-fetch-site": "same-origin",
    "x-litemall-admin-token": "登录凭证(token)",
    "x-litemall-identification": "young"
  },
  "referrer": "https://youthstudy.12355.net/backend/",
  "referrerPolicy": "strict-origin-when-cross-origin",
  "body": null,
  "method": "GET",
  "mode": "cors",
  "credentials": "include"
}).then((e)=>{e.json().then(function(data){
       //此时这里data就是返回回来的数据,打印里面的list属性
       console.log(data.data.list); 
   })});

1626276975.png

js基础数据比对

既然我们拿到了一手数据,那么就要进行数据比对了,康康有谁还没有学习青年大学习,既然需要比对就得准备一个数组用于存放所有的班级同学姓名。

然后使用js进行数据比对,这里我使用了对象存储学生的姓名,通过属性的方式访问可以确定该学生是否学习了青年大学习。

具体原理如下:

//定义一个对象,存放n个已学学生姓名
let obj ={ 'xiaoxi': 1, 'xiaohua': 1 }
//输出1
console.log(obj['xiaoxi'])
//输出undefined
console.log(obj['lihua'])

这样我们就可以通过这种方式obj[姓名]快速确定该学生是否有进行过青年大学习了。

首先对获取到数据进行处理,因为他不仅仅只有姓名,太多数据了,要转成如上一样的对象存储。

我把上面的fetch请求封装成get函数,传入组织id,页码,token即可发起请求,使用了同步的方式获取数据。

    //获取学习名单
    let data = await get(id,1,token)
    //判断页码
    let pages = Math.ceil(data.data.total / data.data.pageSize)
    //把每页的数据存入对象
    for(let i=1;i<pages +1 ;i++){
        let data = await get(id,i,token)
        for(let item of data.data.list){
            learnName[item.name] = 1
        }
    }
    console.log("获取到已学名单:")
    console.log(learnName)

allName就是全部班级学生名字的数组,然后逐个循环遍历,比对数据。

    for(let item of allName){
        if(!learnName[item]){
            noLearnName.push(item)
        }
    }
    console.log("未学名单:")
    console.log(noLearnName)

至此就可以得到了noLearnName未学名单的列表了。

更加通用的改进

显然,我们发现请求是需要组织id和token的,那么组织id每个团支书都是不一样的,我们怎么获取呢?token又得怎么获取呢?相信各位看完上面的分析一定能够找出答案。我把整个可以使用的油猴代码放到文章尾部,感兴趣的同学可以研究。

如何使用

一个可以使用油猴脚本的浏览器

什么360浏览器、edge浏览器、谷歌浏览器都是可以的。但是你得安装油猴插件先,点击你的浏览器的插件市场搜索tampermonkey点击安装,如果你的右上角出现一只猴子就是代表安装成功。温馨提示谷歌浏览器的插件市场需要fq才能访问。
16262780351.png

添加脚本

点击添加新脚本就会打开一个脚本编辑页面。

16262780721.png

粘贴脚本

把自动生成的内容删掉,然后粘贴文章底部的油猴脚本,按下ctrl + s保存脚本,或者点击文件-保存。保存后即可关闭页面。

image.png

尽情使用

此时你就可以尽情使用脚本给你带来的便携。

16262783331.png

完整代码

// ==UserScript==
// @name         智能统计未学学生
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  统计青年大学习的相关信息。
// @author       xiaoxi
// @match        https://youthstudy.12355.net/*
// @icon         https://www.google.com/s2/favicons?domain=12355.net
// @grant        none
// ==/UserScript==
//blog:blog.diyxi.top
(async function() {
    'use strict';
    /*
    *配置全班团员姓名,需要按照下列的方式一个个输入,标点符号不能错!
    */
    let allName = [
        "黄大侠", "刘德华" , "雷军"
    ]



    /*
    *以下代码非专业人士勿改!!
    *以下代码非专业人士勿改!!
    *以下代码非专业人士勿改!!
    *代码出现问题或者不可用请在博客留言!!blog.diyxi.top
    */
    let learnName = {}
    let noLearnName =[]
    //获取cookie中的token
    let token = getCookie("X-Litemall-Admin-Token")
    //获取组织id
    let id = await getId(token)
    id = JSON.parse(id.data.entity).organizeId
    //获取学习名单
    let data = await get(id,1,token)
    //判断页码
    let pages = Math.ceil(data.data.total / data.data.pageSize)
    //把每页的数据存入对象
    for(let i=1;i<pages +1 ;i++){
        let data = await get(id,i,token)
        for(let item of data.data.list){
            learnName[item.name] = 1
        }
    }
    console.log("获取到已学名单:")
    console.log(learnName)
    console.log("班级名单:")
    console.log(allName)
    for(let item of allName){
        if(!learnName[item]){
            noLearnName.push(item)
        }
    }
    console.log("未学名单:")
    console.log(noLearnName)
    let text = `班级团员人数${allName.length}人,已学人数${Object.values(learnName).length}人,未学名单:`
    for(let item of noLearnName){
        text = text +  item + ","
    }
    let code =`
        <div style="background-color: antiquewhite;z-index:99999;position: fixed;top: 0;right: 0;display: flex;flex-direction: column;">
        <div id="xx_iframe" style="display: block;width: 400px;">
            <h1 style="text-align: center;">小熙高级统计工具</h1>
            <p>温馨提示:油猴脚本是权限非常高的,请勿安装来源不明的油猴脚本,当然除了diyxi.top网站里的哈哈哈。</p>
            <p>已学名单:${JSON.stringify(learnName)}</p>
            <p>未学名单:${JSON.stringify(noLearnName)}</p>
            <h2>参考参学率:${ ( Object.values(learnName).length / allName.length).toFixed(2) * 100}%</h2>
            <textarea style="width: 100%;" name="" id="" cols="30" rows="10">${text}</textarea>
        </div>
        <button onclick="document.getElementById('xx_iframe').style.display=='block'?document.getElementById('xx_iframe').style.display='none':document.getElementById('xx_iframe').style.display='block'">隐藏/打开</button>
    </div>`
    let div = document.createElement("div");div.innerHTML  = code
    document.body.appendChild(div)


    async function get(id,page = 1,token) {
        let res =  await fetch(`https://youthstudy.12355.net/apibackend/admin/young/organize/userList?organizedId=${id}&pageNo=` + page, {
            "headers": {
                "accept": "application/json, text/plain, */*",
                "accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
                "cache-control": "no-cache",
                "pragma": "no-cache",
                "sec-fetch-dest": "empty",
                "sec-fetch-mode": "cors",
                "sec-fetch-site": "same-origin",
                "x-litemall-admin-token": token,
                "x-litemall-identification": "young"
            },
            "referrer": "https://youthstudy.12355.net/backend/",
            "referrerPolicy": "strict-origin-when-cross-origin",
            "body": null,
            "method": "GET",
            "mode": "cors",
            "credentials": "include"
        });
        let data = await res.json()
        return data
    }
    async function getId(token) {
        let res =  await fetch("https://youthstudy.12355.net/apibackend/admin/young/QRCode", {
            "headers": {
                "accept": "application/json, text/plain, */*",
                "accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
                "cache-control": "no-cache",
                "pragma": "no-cache",
                "sec-fetch-dest": "empty",
                "sec-fetch-mode": "cors",
                "sec-fetch-site": "same-origin",
                "x-litemall-admin-token": token,
                "x-litemall-identification": "young"
            },
            "referrer": "https://youthstudy.12355.net/backend/",
            "referrerPolicy": "strict-origin-when-cross-origin",
            "body": null,
            "method": "POST",
            "mode": "cors",
            "credentials": "include"
        });
        let data = await res.json()
        return data
    }
    // 获取指定名称的cookie
    function getCookie(name){
        var strcookie = document.cookie;//获取cookie字符串
        var arrcookie = strcookie.split("; ");//分割
        //遍历匹配
        for ( var i = 0; i < arrcookie.length; i++) {
            var arr = arrcookie[i].split("=");
            if (arr[0] == name){
                return arr[1];
            }
        }
        return "";
    }

})();