系统更新加入了对额温的数值校验,可以加一句

cph_right_rv_temp.minimumvalue = "0";  // 修改额温校验数值下限为0

方便那些家里没体温计的同学将额温填为0 XDDD

const playwright = require('playwright');
const schedule = require('node-schedule');
const {exec} = require('child_process');
const fs = require('fs');

const V = {
}

;(async () => {
    const browser = await playwright.chromium.launch({
        // devtools: true,
        // headless: false,
        slowMo: 5
    });
    const ctx = await browser.newContext();
    const page = await ctx.newPage();

    await loginSSP(page);
    await go(page);
    // await keepSession(page);

    // let id = setInterval(() => keepSession(page), 1000 * 60 * 3) // 3 min



    // await page.close();
})()

const keepSession = async (page) => {
    await page.goto('https://ssp.scnu.edu.cn/Default.aspx');
    await page.reload();
}

const loginSSP = async (page) => {
    await page.goto('https://ssp.scnu.edu.cn/Default.aspx');
    await page.setViewportSize({ width: 1536, height: 722 });
    await page.waitForSelector('nav > .menu > .login_info > #gologin > a:nth-child(2)')
    await page.click('nav > .menu > .login_info > #gologin > a:nth-child(2)')
        
    await page.waitForSelector('#codeimg');
    await page.waitForResponse(/rancode\.jpg\?m=/);
    await page.screenshot({ path: 'a.png' });
    
    exec('xdg-open a.png');

    let code = fs.readFileSync(0, 'utf-8');
    if(code.endsWith('\n')) code = code.substring(0, code.length-1);
    console.log(code);
    const codeInput = await page.$('#rancode');
    await codeInput.type(code);
    await page.type('#account', V.account);
    await page.type('#password', V.password);
    await page.screenshot({ path: 'aa.png' });

    await page.evaluate('loginfunc();');
    await page.waitForSelector('.menu > li:nth-child(4) > ul > .bg0 > a', {
        timeout: 50 * 1000
    });
}

const go = async (page) => {
    // const page = await ctx.newPage();
    // await page.screenshot({ path: 'aaa.png' });
    await page.goto('https://ssp.scnu.edu.cn/Default.aspx');
    const btn = await page.$$eval('a[href]', as => {
        const btn = [...as].find(e => /opt_rc_jkdk/.test(e.href));
        btn.click();
        return btn;
    });
    
    await page.waitForSelector('#cph_right_ok_submit');
    await page.click('#cph_right_ok_submit');
    await page.waitForSelector('#cph_right_e_observation #cph_right_e_observation_0');
    await page.screenshot({path: 'aaaa.png'});

    await page.click('#cph_right_e_atschool #cph_right_e_atschool_1'); // 没返校
    await page.type('#cph_right_e_location', V.location);
    await page.click('#cph_right_e_observation_0'); // 无情况
    await page.click('#cph_right_e_health_0'); // 无不适
    await page.type('#cph_right_e_temp', V.temp);
    // await page.click('#cph_right_e_submit'); // 提交
}

    Tover 大佬冲呀

    我现在是挂着5分钟刷新一次保持session,。到现在差不多24小时过去了,session还在。如果session能保持住的话登一次也还是能够接受的。

    9 天 后
    3 个月 后

    写了个 Bookmarklet 版的,只需在书签点点点就可以完成了,避免频繁移动鼠标造成腱鞘炎(逃

    javascript:(() => {
      const Val = {
        area: '广东省', /* 地区 */
        location: '广州市天河区', /* **市**县(区)*/
        temp: 0, /* 实测额温 */
      };
    
      if (location.origin !== "https://ssp.scnu.edu.cn") {
        location.href = "https://ssp.scnu.edu.cn";
      } else if (document.querySelector("#gologin")) {
        document.querySelector("#gologin > a:nth-child(2)").click();
      } else if (location.pathname !== "/opt_rc_jkdk.aspx") {
        let healthBtn = document.querySelector(".bg_health > a");
        if (healthBtn) {
          healthBtn.click();
        } else if (location.pathname === "/opt_xx_myapps.aspx") {
          document.querySelector("#cph_right_myapps .bg0 > a").click();
        }
      } else {
        let step1Btn = document.querySelector("#cph_right_ok_submit");
        if (step1Btn) {
          step1Btn.click();
        } else {
          document.querySelector("#cph_right_e_area").value = Val.area;
          document.querySelector("#cph_right_e_location").value = Val.location;
          document.querySelector("#cph_right_e_observation_0").click();
          document.querySelector("#cph_right_e_health_0").click();
          document.querySelector("#cph_right_e_temp").value = Val.temp;
          document.querySelector("#cph_right_e_survey01_0").click();
          /* document.querySelector("#cph_right_e_submit").click(); */ /* 提交 */
        }
      }
    })();

    使用方法,修改代码,新建书签,粘贴,保存在书签栏:

    然后点点点... 即可:

      0x0001 亲测成功!不过为啥在控制台能运行,放进书签就不行了?(qwqq一定是我打开的方式不对

      • cr19 回复了此帖

        coo 我猜你是把站长写的注释也复制进去了hhh
        添加到书签会自动去掉换行符,等于把第一个注释符后面的内容全部注释掉了
        可以jsmin最小化一下js代码,去掉注释、缩进和换行再添加到书签上

          cr19 最新的这个放进书签还是不行qwqqq

          再次更进反馈!!搞定啦!!!直接在空白网页点就没反应,随便开一个别的网页就可以用了

            coo 因为 Chrome 的“新标签页”没法直接通过 javascript: 形式的链接实现注入脚本

            • coo 觉得很赞

            0x0001 的脚本上加了本地登录,并且粗暴地把点击次数缩减到5下,打卡这么多天才知道本地登录不用验证码也是没谁了🌚

            javascript: (() => {
                const CONF = {
                    area: '**省',
                    location: '**市**区',
                    temp: Math.round(358 + Math.random() * 5) / 10,
                    username: '账号',
                    password: '密码'
                };
                if (location.origin !== 'https://ssp.scnu.edu.cn') {
                    window.open('https://ssp.scnu.edu.cn/login.aspx');
                } else if (document.querySelector('#gologin')) {
                    document.querySelector('#gologin > a').click();
                } else if (location.pathname === '/login.aspx') {
                    document.querySelector('#log_username').value = CONF.username;
                    document.querySelector('#log_password').value = CONF.password;
                    document.querySelector('#logon').click();
                } else if (location.pathname !== '/opt_rc_jkdk.aspx') {
                    location.href = document.querySelector('.menu > li:nth-child(2) > a').href.replace('xx_myapps', 'rc_jkdk').split('&fid=')[0] + '&fid=55';
                } else {
                    let startBtn = document.querySelector('#cph_right_ok_submit');
                    if (startBtn) {
                        startBtn.click();
                    } else {
                        document.querySelector('#cph_right_e_area').value = CONF.area;
                        document.querySelector('#cph_right_e_location').value = CONF.location;
                        document.querySelector('#cph_right_e_observation_0').click();
                        document.querySelector('#cph_right_e_health_0').click();
                        document.querySelector('#cph_right_e_temp').value = CONF.temp;
                        document.querySelector('#cph_right_e_survey01_0').click();
                        document.querySelector('#cph_right_e_submit').click();
                    }
                }
            })();

              贴一个python3的,写个批处理放在自启动目录,每天打开电脑即可,美汁汁。

              # -*- coding:utf8 -*-
              import random
              import requests
              import re
              import tkinter.messagebox as tk
              
              login_html = ''
              temp_html = ''
              clock_html = ''
              
              # 填写下面信息即可
              tem = 37 - random.randint(5, 10) / 10  # 正常温度:36° - 36.5°
              user = '2020xxxxx'         # 你的学号
              password = 'password'      # 你的密码
              area = 'xx省'              # 你的省份
              location = 'xx市xx县'      # 详细位置
              
              try:
              
              	# 抓取网页上的__VIEWSTATE 等参数
              	def get__(target, html):
              		'''
              		抓取网页上的__VIEWSTATE 等参数用于post
              		:param target: 要抓取的参数名
              		:param html:   抓取参数所在的html文本
              		:return: 返回参数的值
              		'''
              		text = 'id="' + target + '" value="'
              		res = re.search(text + '[/+=\w]+"', html)  # 查找含有类似于id="__VIEWSTATE" value="/wsdijd...."的字段
              		start = res.span()[0] + len(text)
              		end = res.span()[1] - 1
              		return html[start:end]  # 截取参数内容返回
              
              
              	# 打卡提交数据
              	data = {
              		# 两个标志是必要的
              		'__VIEWSTATE': '',
              		'__EVENTVALIDATION': '',
              
              		# 打卡表单内容
              		'ctl00$cph_right$e_area': area,
              		'ctl00$cph_right$e_location': location,
              		'ctl00$cph_right$e_observation': '无下列情况',
              		'ctl00$cph_right$e_health$0': '无不适',
              		'ctl00$cph_right$e_temp': str(tem),
              		'ctl00$cph_right$e_describe': '',
              		'ctl00$cph_right$e_survey01': '疫情期间未出国出境',
              		'ctl00$cph_right$e_submit': '提交保存'
              	}
              
              	# 登录Requests Header
              	login_head = {
              		'Origin': 'https://ssp.scnu.edu.cn',
              		'Referer': 'https://ssp.scnu.edu.cn/login.aspx',
              		'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36'
              	}
              
              	# 打卡Requests Header
              	clock_head = {
              		'Origin': 'https://ssp.scnu.edu.cn',
              		'Referer': '',
              		'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36',
              	}
              
              	# 登录界面
              	s = requests.session()
              	login_url = 'https://ssp.scnu.edu.cn/login.aspx'  # 登录url
              	login = s.get(login_url)
              	login_html = login.text
              
              	# 登录Requests  Data
              	login_data = {
              		# '__VIEWSTATEGENERATOR': 'C2EE9ABB',
              		'__EVENTTARGET': 'logon',
              		'__VIEWSTATE': get__('__VIEWSTATE', login_html),
              		'__EVENTVALIDATION': get__('__EVENTVALIDATION', login_html),
              		'log_username': user,
              		'log_password': password
              	}
              
              	# 向登录页面post数据
              	res = s.post(url=login_url, data=login_data, headers=login_head)
              
              	# 利用登录后网页源代码查找key
              	# 因为打卡页面上参数key每次登录都会变化
              	# 找到key就可以定位到打卡页面
              	temp_html = res.text
              	start = temp_html.find('opt_rc_jkdk.aspx?')
              	end = temp_html.find('>健康打卡') - 1
              	clock_site = 'https://ssp.scnu.edu.cn/' + temp_html[start:end]  # 截取key获得打卡网址
              	clock_head['Referer'] = clock_site  # 用打卡网址更新 Requests Header 的参数
              
              	clock_html = s.get(clock_site).text  # 用于中间Requests Data查找请求参数
              
              	# 中间Requests Data
              	temp_data = {
              		'ctl00$cph_right$e_ok': 'on',
              		'ctl00$cph_right$ok_submit': '开始填报',
              		# '__VIEWSTATEGENERATOR':'DC47EEF4',
              
              		'__VIEWSTATE': get__('__VIEWSTATE', clock_html),
              		'__EVENTVALIDATION': get__('__EVENTVALIDATION', clock_html)
              	}
              
              	# 进入打卡页面
              	res = s.post(url=clock_site, data=temp_data, headers=clock_head)
              	clock_html = res.text
              
              	# 更新打卡Data
              	data['__VIEWSTATE'] = get__('__VIEWSTATE', clock_html)
              	data['__EVENTVALIDATION'] = get__('__EVENTVALIDATION', clock_html)
              
              	# 提交打卡内容
              	res2 = s.post(url=clock_site, data=data, headers=clock_head)
              
              	if res2.text.find('打卡成功') == -1:
              		tk.showwarning('打卡失败!','请查看打卡内容是否变更!')
              	else:
              		tk.showinfo('打卡成功', '温度为:' + str(tem))
              except Exception as e:
              	tk.showerror('打卡失败!', '请查看error log')
              	with open('error log.txt','w') as f:
              		f.write(str(e))
              		f.write('====='*6 + '\n')
              		f.write(login_html)
              		f.write('====='*6 + '\n')
              		f.write(temp_html)
              		f.write('====='*6 + '\n')
              		f.write(clock_html)

                cr19 我靠,太爽了哈哈哈!我的还要登录sso(

                打卡最痛的点就在于每次都要重新填,点下鼠标,又得敲下键盘 = =,天天宅家,填的东西还重复。

                cr19 顺手写个油猴 , 只用点一次(需要自己点提交 ,如果确定每天都一样可以自己加上)

                // ==UserScript==
                // @name         健康打卡
                // @namespace    http://tampermonkey.net/
                // @version      0.1
                // @description  一波带走
                // @author       cr19
                // @match        https://ssp.scnu.edu.cn/*
                // @grant        none
                // ==/UserScript==
                
                (function() {
                    'use strict';
                
                    const CONF = {
                        area: '**省',
                        location: '**市**区',
                        temp: Math.round(358 + Math.random() * 5) / 10,
                        username: '账号',
                        password: '密码'
                    };
                    if (location.origin !== 'https://ssp.scnu.edu.cn') {
                        window.open('https://ssp.scnu.edu.cn/login.aspx');
                    } else if (document.querySelector('#gologin')) {
                        document.querySelector('#gologin > a').click();
                    } else if (location.pathname === '/login.aspx') {
                        document.querySelector('#log_username').value = CONF.username;
                        document.querySelector('#log_password').value = CONF.password;
                        document.querySelector('#logon').click();
                    } else if (location.pathname !== '/opt_rc_jkdk.aspx') {
                        location.href = document.querySelector('.menu > li:nth-child(2) > a').href.replace('xx_myapps', 'rc_jkdk').split('&fid=')[0] + '&fid=55';
                    } else if(document.querySelector('#SysErrMsg').innerText != ''){
                        document.querySelector('#left_menu > li:nth-child(1) > a').click();
                    }else{
                        let startBtn = document.querySelector('#cph_right_ok_submit');
                        if (startBtn) {
                            startBtn.click();
                        } else  if(document.querySelector('#cph_right_e_temp') && !document.querySelector('#cph_right_e_temp').value){
                            document.querySelector('#cph_right_e_area').value = CONF.area;
                            document.querySelector('#cph_right_e_location').value = CONF.location;
                            document.querySelector('#cph_right_e_observation_0').click();
                            document.querySelector('#cph_right_e_health_0').click();
                            document.querySelector('#cph_right_e_temp').value = CONF.temp;
                            document.querySelector('#cph_right_e_survey01_0').click();
                            // document.querySelector('#cph_right_e_submit').click();
                        }
                    }
                })();

                  aukocharlie 用油猴自动提交的话需要注意重复执行的问题,可以在最后一个else后面加上if (document.querySelector('#cph_right_e_temp') && !document.querySelector('#cph_right_e_temp').value)判断

                    3 个月 后

                    © 2018-2025 0xFFFF