01月26, 2021

自动实现每日疫情上报

注意

本脚本仅作为每日上报的辅助工具,具体信息请结合个人情况进行修改

代码来源

本文selenium部分代码沿用了阮行止的 自动实现每日疫情上报 ,并针对2021.08.16新的每日上报系统进行了js脚本的修改,并增加了自动执行、自动警报的功能。

软件版本

似乎geckodriver与firefox版本一致性要求比较高,所以列一下我一直在使用的版本。

  • geckodriver 0.29.0
  • firefox 59.0.2

更新记录

2021.01.26学工系统更新

  • 取消了手动输入地址,变为自动获取定位输入
  • 提交前的"我已仔细阅读并同意"选择框的id由"txfscheckbox"变为"checkbox"
  • 点击提交会弹出一个confirm框

2021.08.13更新

  • 地址栏value变为innerHTML
  • 增加自动杀firefox进程
  • 增加自动发送错误报告邮件功能

2021.08.16更新

  • 每日上报换了新系统
  • 将js脚本分离出一个文件

新系统脚本

js脚本

该部分请详细阅读脚本中的注释,根据自己实际情况进行修改

新建一js文件,命名为mrsb.js,内容如下:

vim mrsb.js
var i;

//这一行为详细地址
$('<script>function changekzl10(){kzl10 = "黑龙江省哈尔滨市南岗区曲线街道哈尔滨工业大学西苑小区";}</script>').appendTo(document.body);

//这一行为经纬度
$('<script>function changegps(){gpsjd = 126.63191; gpswd = 45.73923;}</script>').appendTo(document.body);

//这三行为省市区
$('<script>function changekzl678(){kzl6 = "黑龙江省"; kzl7 = "哈尔滨市"; kzl8 = "南岗区";}</script>').appendTo(document.body);
$('<script>function changekzl38(){kzl38 = "黑龙江省"; kzl39 = "哈尔滨市"; kzl40 = "南岗区";}</script>').appendTo(document.body);
document.getElementById("dtjwd").getElementsByTagName("a")[0].innerHTML = "黑龙江省哈尔滨市南岗区";

//这一行为街道+门牌号
$('<script>function changekzl9(){kzl9 = "护军街4-1号";}</script>').appendTo(document.body);

//国内/国外
//若为国外则可能需要填写其他信息,请自行补完脚本
var list1 = document.getElementsByName('kzl1');
for(i = 0;i<list1.length;i++){
    if(list1[i].offsetParent.innerHTML.search("国内") != -1) {
        if(!list1[i].checked){
            list1[i].click();
        }
    }
}

//低风险/中风险/高风险地区
//若不为低风险地区则可能需要填写其他信息,请自行补完脚本
var list13 = document.getElementsByName('kzl13');
for(i = 0;i<list13.length;i++){
    if(list13[i].offsetParent.innerHTML.search("低风险") != -1) {
        if(!list13[i].checked){
            list13[i].click();
        }
    }
}

//当日是否途径中高风险地区
//若为是则可能需要填写其他信息,请自行补完脚本
var list15 = document.getElementsByName('kzl15');
for(i = 0;i<list15.length;i++){
    if(list15[i].offsetParent.innerHTML.search("否") != -1) {
        if(!list15[i].checked){
            list15[i].click();
        }
    }
}

//今日体温范围, 37.2度以上/以下
//若为以上则可能需要填写其他信息,请自行补完脚本
var list17 = document.getElementsByName('kzl17');
for(i = 0;i<list17.length;i++){
    if(list17[i].offsetParent.innerHTML.search("以下") != -1) {
        if(!list17[i].checked){
            list17[i].click();
        }
    }
}

//今日是否出现不适
//若不为"无不适"则可能需要填写其他信息,请自行补完脚本
var list18 = document.getElementsByName('kzl18');
for(i = 0;i<list18.length;i++){
    if(list18[i].parentElement.parentElement.innerHTML.search("无不适") != -1) {
        if(!list18[i].checked){
            list18[i].click();
        }
    }
}

//当前的健康状况,正常/无症状感染者/确诊病例
//若不为"正常"则可能需要填写其他信息,请自行补完脚本
var list23 = document.getElementsByName('kzl23');
for(i = 0;i<list23.length;i++){
    if(list23[i].offsetParent.innerHTML.search("正常") != -1) {
        if(!list23[i].checked){
            list23[i].click();
        }
    }
}

//是否处于隔离期
//若为是则可能需要填写其他信息,请自行补完脚本
var list24 = document.getElementsByName('kzl24');
for(i = 0;i<list24.length;i++){
    if(list24[i].offsetParent.innerHTML.search("否") != -1) {
        if(!list24[i].checked){
            list24[i].click();
        }
    }
}

//本人或共同居住的家人是否与确诊病例、无症状感染者、疑似病例行程轨迹有交集
//若为是则可能需要填写其他信息,请自行补完脚本
var list28 = document.getElementsByName('kzl28');
for(i = 0;i<list28.length;i++){
    if(list28[i].offsetParent.innerHTML.search("否") != -1) {
        if(!list28[i].checked){
            list28[i].click();
        }
    }
}

//本人48小时内是否已进行核酸检测
var list31 = document.getElementsByName('kzl31');
for(i = 0;i<list31.length;i++){
    if(list31[i].offsetParent.innerHTML.search("否") != -1) {
        if(!list31[i].checked){
            list31[i].click();
        }
    }
}

//以下为疫苗接种情况,根据情况修改
//未接种
//已接种部分剂次
//已接种全部剂次
var list32 = document.getElementsByName('kzl32');
for(i = 0;i<list32.length;i++){
    if(list32[i].offsetParent.innerHTML.search("已接种全部剂次") != -1) {
        if(!list32[i].checked){
            list32[i].click();
        }
    }
}

//龙江健康码颜色
var list41 = document.getElementsByName('kzl41');
for(i = 0;i<list41.length;i++){
    if(list41[i].offsetParent.innerHTML.search("绿") != -1) {
        if(!list41[i].checked){
            list41[i].click();
        }
    }
}


changekzl10();
changegps();
changekzl678();
changekzl38();
changekzl9();

if(!document.getElementById("txfscheckbox1").checked){
    document.getElementById("txfscheckbox1").click();
}

if(!document.getElementById("txfscheckbox2").checked){
    document.getElementById("txfscheckbox2").click();
}

if(!document.getElementById("txfscheckbox3").checked){
    document.getElementById("txfscheckbox3").click();
}

if(save() == false){
    throw Error(document.getElementsByClassName("weui-toptips_visible")[0].innerHTML);
}

python脚本

新建一py文件,命名为mrsb.py,内容如下:

vim mrsb.py
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
import time

opt = Options()
opt.add_argument('--headless')
browser = webdriver.Firefox(options=opt)
time.sleep(3)
url = 'http://xg-hit-edu-cn-s.ivpn.hit.edu.cn:1080/zhxy-xgzs/xg_mobile/xsMrsbNew/edit'

browser.get(url)
time.sleep(3)
browser.find_element_by_id('username').send_keys('学号') # 此处为你的学号
browser.find_element_by_id('password').send_keys('密码') # 此处为你的密码
browser.find_element_by_id('login_submit').click()
time.sleep(5)

browser.get(url)

js = ""
with open("/home/ubuntu/zireael/mrsb.js", "r") as f:
    js = f.read()

time.sleep(3)
browser.execute_script(js)

time.sleep(4)

browser.close()

每日自动执行脚本

使用crontab定期执行命令。

输入crontab -e打开文字编辑器,新建一行:

0 7 * * * python3 /home/ubuntu/zireael/mrsb.py > /home/ubuntu/zireael/mrsb.log 2>&1 &

代表每天7点执行一次python3 /home/ubuntu/zireael/mrsb.py命令,并将日志记录在/home/ubuntu/zireael/mrsb.log

保存退出即可。

自动杀firefox进程

在长达一年的使用中发现,如果在脚本运行时firefox已经启动,则脚本连接firefox会报错。

可以新建一脚本killfirefox.sh来杀firefox进程:

vim killfirefox.sh
ps -ef|grep -v grep|grep firefox|while read u p o
do
kill -9 $p
done

保存退出,增加执行权限:

sudo chmod +x killfirefox.sh

同样,打开crontab,将其加入定时执行列表

crontab -e

新增一行

0 8 * * * /home/ubuntu/zireael/killfirefox.sh

自动发送错误日志警报

若上报脚本出现错误,则可通过自动发送邮件的方法通知错误信息,使用python3的smtplib完成。

pip3 install py-emails

新建一py文件:

import smtplib
import time
from email.mime.text import MIMEText
from email.header import Header

mail_host = "smtp.163.com" #填所用发件邮箱的smtp服务器地址,我用的是163邮箱
mail_user = "用户名" #填邮件中显示的姓名
mail_password = "密码" #这里填你邮箱的密码/授权码
sender = '发件邮箱地址' #填发件邮箱地址
receivers = ['收件邮箱地址'] #填收件邮箱地址

log = ''
with open("/home/ubuntu/zireael/mrsb.log", "r") as f: #填你每日上报脚本输出的日志,在crontab中我重定位到了该文件中
    log = f.read()

if len(log) == 0: #若正常执行,则无需发送邮件警报
    exit(0)

message = MIMEText(log,'plain','utf-8')
message['Subject'] = time.strftime("%Y.%m.%d") + ' 每日上报日志'
message['From'] = sender
message['To'] = receivers[0]

try:
    smtpObj = smtplib.SMTP_SSL(mail_host)
    smtpObj.login(mail_user,mail_password)
    smtpObj.sendmail(sender,receivers,message.as_string())
    smtpObj.quit()
except smtplib.SMTPException as e:
    print(e)

然后在crontab中添加自动执行该脚本的条目,同样,打开crontab编辑器:

crontab -e

新增一行:

0 8 * * * python3 /home/ubuntu/zireael/mail.py > /home/ubuntu/zireael/mail.log 2>&1 &

以下为旧版系统内容

旧系统归档

2021.01 界面改动

详细地址页面仍旧是一个输入框,但是变为只读。页面加载后前端申请定位信息自动填写,若浏览器没有给定位权限,则会填写为获取位置失败,请打开位置权限!

在点击提交后,前端会判断地址一栏是否为空,或是否含有"失败"字样,若是则会提交失败。

if($("#gnxxdz").val()==""){
    $.toptip("【获取位置失败,请打开位置权限!】","warning");
    return false;
}
if(dqszd == "01" && $("#gnxxdz").val().indexOf("失败")!=-1){
    $.toptip("【获取位置失败,请打开位置权限!】","warning");
    return false;  
}

若一切正常,则会弹出一个确认框,确认是否提交。

对于向只读框中填写地址,可以使用execute_script()方法执行一段js语句来完成。

browser.execute_script('document.getElementById("gnxxdz").value="黑龙江省哈尔滨市南岗区西大直街92号"')

对于选择确认框中的确认,也是用同样方法。

browser.execute_script('document.getElementsByClassName("weui-dialog__btn primary")[0].click()')

旧系统脚本

from selenium import webdriver
from selenium.webdriver.firefox.options import Options
import time

opt = Options()
opt.add_argument('--headless')
browser = webdriver.Firefox(options=opt)
url = 'https://xg.hit.edu.cn/zhxy-xgzs/xg_mobile/xs/yqxx'

browser.get(url)
browser.find_element_by_id('username').send_keys('学号') #此处更改为你的学号
browser.find_element_by_id('password').send_keys('密码') #此处更改为你的密码
browser.find_element_by_id('casLoginForm').submit()
time.sleep(2) #延迟自定,尽量大一些

browser.get(url)
time.sleep(2)
browser.execute_script('add()')
time.sleep(2)
browser.execute_script('document.getElementById("gnxxdz").innerHTML="地址"') #此处更改为你所在地址
time.sleep(2)
browser.execute_script('document.getElementById("gnxxdz").innerHTML="地址"') #此处更改为你所在地址
time.sleep(2)
browser.find_element_by_id('checkbox').click()
time.sleep(2)
browser.execute_script('save()')
time.sleep(2)
browser.execute_script('document.getElementsByClassName("weui-dialog__btn primary")[0].click()')
time.sleep(2)
browser.close()

本文链接:http://blog.zireaels.com/post/selenium.html

-- EOF --

Comments