python微信小程序自动打卡,python微信小程序打卡

大家好,小编来为大家解答以下问题,python微信小程序自动打卡,python微信小程序打卡,现在让我们一起来看看吧!

前言:
某公司可以使用OA系统进行打卡,前提是要在公司内网,也就是必须要在公司才能打卡,实际工作中经常会遇到忘记打卡或者迟到早退的情况(嘿嘿你懂的),于是就想写个小程序来实现自动打卡。其实这也可以视为OA系统的一个跨站请求伪造(CSRF)漏洞Python画流程图。要堵住这个漏洞可以使用四种方法:
1、随机TOKEN,打卡请求时携带一个随机TOKEN
2、图形验证码,打卡请求时输入一个随机验证码
3、Referrer头验证,打卡请求时验证Referrer头已判断来源
4、输入密码,打卡请求时输入自己的密码
在这里插入图片描述
在这里插入图片描述
代码逻辑说明:

由于tkinter不能使用类似schedule的调度模块,也不能使用time.sleep,主要原因是tkinter的GUI是靠window.mainloop()的循环实现,当使用schedule或time.sleep时,函数会暂停跳不到window.mainloop()导致界面会卡死。tkinter为了实现定时任务提供了自己的after方法。其功能是指定一定的时间(毫秒)后执行某函数。因此这个定时打卡退卡程序反复使用tkinter的after来实现。思路如下:
一、当点击button按钮进入start_time函数,主要功能是无论何时启动打卡,都能在设置的打卡时间进行打卡,退卡时间进行退卡。实现如下:
1、 先获取当前时间,再设置一个打卡时间workon_time和一个退卡时间workoff_time;
2、 分别计算打卡时间到当前时间之间的打卡毫秒数minsecond和退卡时间到当前时间的退卡毫秒数minsecond1;
3、 设置两个window.after定时任务,一个是minsecond毫秒后启动start_time1函数;另一个是minsecond1毫秒后启动start_time1函数;
二、start_time1函数的作用是实现循环打卡,也就是本次执行后每24小时后再执行一次,实现如下:
1、 该函数启动先执行一次randomtimes函数,24小时(86400000毫秒)后再执行一次自己(同时再次先执行一次randomtimes),以实现循环执行;
2、 start_time2和start_time1一样,只不过一个在打卡时间时启动循环,另一个在退卡时间启动循环
三、randomtimes函数的主要功能是随机时间打卡,以防止每次打开时间相同让人起疑,实现如下:
1、 在一定的范围内(这里设置的是360秒)随机一个秒数s;
2、 在s秒后开始执行真正的打卡函数work_on;
3、 randomtimes1函数和randomtimes功能相似;
四、work_on函数的作用是模拟登陆后打卡,都是由requests模块实现,不再详说;

举例(以打卡为例):
假如打卡时间是上午8:30,当前时间是上午8:00,我启动了此程序,点击了‘按钮’,程序先执行了start_time函数;
start_time函数获取了当前时间8:00,计算出30分钟后(也就是8:30)开始执行start_time1函数;
start_time1函数先执行了randomtimes函数,然后再执行一个计划任务——24小时后再执行一次自己;
randomtimes函数随机了一个秒数60秒,并在60秒后执行work_on函数;
60秒后(8:31时)work_on正式启动,第1次打卡;
24小时后(第二天8:30)…
start_time1再次启动了自己,执行了randomtimes函数,同时又执行一个计划任务——24小时后再执行一次自己;
randomtimes函数这次随机120秒,并在120秒后执行work_on函数;
120秒后(8:32时)work_on正式启动,第2次打卡;
24小时后(第三天8:30)…

代码:

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @Time     :2020/6/28 10:43
# @Author   :Donvin.li
# @File     :autologin_v1.py

import requests
import rsa
import time
import random
import tkinter as tk
from tkinter import ttk
import datetime
import json

def basedesk(root):
    root.config()
    root.title('江波龙自动打卡')
    root.geometry('355x355')

    interface(root)

# 主窗口,主要实现登录功能,成功后跳转到框架窗口
def interface(root):
    master=root
    master.config(bg='green')
    interface=tk.Frame(master)
    interface.pack(expand='yes', fill='both')
    #interface.place(x=0,y=0)

    l1 = tk.Label(interface, text='用户名:', font=('Arial', 10))
    l1.place(x=50,y=50)

    e1 = tk.Entry(interface, width=20, show=None)  # 显示成明文形式
    e1.place(x=130, y=50)

    l2 = tk.Label(interface, text='密  码:', font=('Arial', 10))
    l2.place(x=50, y=80)

    e2 = tk.Entry(interface, width=20, show='*')  # 显示成密文形式
    e2.place(x=130, y=80)

    # RSA加密函数,实现模拟前端RSA加密,加密后的字符串(密码)被logintest函数调用
    def get_rsa_result(content):
        """
        根据 模量与指数 生成公钥,并利用公钥对内容 rsa 加密返回结果
        :param e:指数
        :param n: 模量
        :param content:待加密字符串
        :return: 加密后结果
        """
        n = "8bcbceb956d3d6c0da8cd8847e50796eac0fb3d67d4901820fa85dcd8edbb30bd25966eb18223e1ace1308da181897df4559bf97cca6ae9a33a0baf6f53324334a385d2a7cbc186fb5070045080b6c948423e7ddcd795ac9eaa438317772f4a948409ecec92dfe222a10b4c327e8d0e494cc0aa42ebc786030a105da0637049d"
        e = "10001"
        e = int(e, 16)
        n = int(n, 16)

        pub_key = rsa.PublicKey(e=e, n=n)
        m = rsa.encrypt(content.encode(), pub_key)
        # print(m.hex())
        return m.hex()

    def logintest1():
        usr = e1.get()
        psd = e2.get()
        change(usr, psd)

    # 登录函数,主要实现验证账号密码功能。
    def logintest():
        usr = e1.get()
        psd = e2.get()
        passd = get_rsa_result(psd)
        s = requests.session()
        headers = {'Host': 'e.xxxx.com',
                   'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0',
                   'Accept': 'application/json, text/java, */*; q=0.01',
                   'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
                   'Accept-Encoding': 'gzip, deflate',
                   'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
                   'X-Requested-With': 'XMLHttpRequest',
                   'Origin': 'http://e.xxxx.com',
                   'Connection': 'close',
                   'Referer': 'http://e.xxxx.com/portal/',
                   }
        postdata = {'lang': 'cn', 'userid': usr, 'pwd': passd, 'cmd': 'CLIENT_USER_LOGIN', 'sid': '',
                    'deviceType': 'pc', '_CACHE_LOGIN_TIME_': '1579162050273', 'pwdEncode': 'RSA', 'timeZone': '-8'}
        url = 'http://e.xxxx.com/portal/r/jd'
        rs = s.post(url, postdata, headers=headers)
        result = rs.text
        if 'error' not in result:
            ts = '登录成功,开始自动打卡守护,请勿关闭程序\n'
            t1.insert(tk.INSERT, ts)
            change(usr,psd)  #登录执行此函数
            return 'OK'
        else:
            tishi = '登录失败,请重新登录\n'
            t1.insert(tk.INSERT, tishi)

    # 跳转函数,实现跳转到窗口1功能
    def change(usr,psd):
        interface.destroy()
        interface1(usr,psd)    #窗口1函数



    b1 = tk.Button(interface, text='登 录', width=10, height=1, command=logintest)
    b1.place(x=130, y=120)

    t1 = tk.Text(interface, bg='green', fg='white', width=47, height=9)
    # 说明: bg为背景,fg为字体颜色,font为字体,width为长,height为高,这里的长和高是字符的长和高,比如height=2,就是标签有2个字符这么高
    t1.place(x=10, y=180)

    l3 = tk.Label(interface, text='作者:沙漠网管', font=('Arial', 10))
    l3.place(x=130, y=320)


# 窗口1函数,实现打卡功能
def interface1(usr,psd):
    master = root
    master.config(bg='blue')
    interface1 = tk.Frame(master)
    interface1.pack(expand='yes', fill='both')

    xVariable = tk.StringVar()  # #创建变量,便于取值
    l1 = tk.Label(interface1, text='打卡时间', font=('Arial', 10))
    l1.place(x=20,y=20)

    com = ttk.Combobox(master, textvariable=xVariable,width=3)  # #创建下拉菜单
    #com.pack()  # #将下拉菜单绑定到窗体
    com.place(x=20, y=50)
    com["value"] = ("7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22")  # #给下拉菜单设定值
    com.current(1)  # #设定下拉菜单的默认值为第2个

    def xFunc(event):
        #print(com.get())   #获取选中的值方法1
        xVariable.get()     #获取选中的值方法2

    com.bind("<<ComboboxSelected>>", xFunc)  # #给下拉菜单绑定事件

    xVariable1 = tk.StringVar()
    com1 = ttk.Combobox(master, textvariable=xVariable1, width=3)  # #创建下拉菜单
    # com.pack()  # #将下拉菜单绑定到窗体
    com1.place(x=60, y=50)
    com1["value"] = ("00","05","10","15","20","25","30","35","40","45","50","55")  # #给下拉菜单设定值
    com1.current(10)  # #设定下拉菜单的默认值为第2个

    def xFunc1(event):
        #print(com1.get())  # #获取选中的值方法1
        xVariable1.get()  # #获取选中的值方法2

    com1.bind("<<ComboboxSelected>>", xFunc1)  # #给下拉菜单绑定事件

    l2 = tk.Label(interface1, text='退卡时间', font=('Arial', 10))
    l2.place(x=220,y=20)

    xVariable2 = tk.StringVar()
    com2 = ttk.Combobox(master, textvariable=xVariable2,width=3)  # #创建下拉菜单
    #com.pack()  # #将下拉菜单绑定到窗体
    com2.place(x=220, y=50)
    com2["value"] = ("7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22")  # #给下拉菜单设定值
    com2.current(11)  # #设定下拉菜单的默认值为第2个

    def xFunc2(event):
        #print(com2.get())  # #获取选中的值方法1
        xVariable2.get()  # #获取选中的值方法2

    com2.bind("<<ComboboxSelected>>", xFunc2)  # #给下拉菜单绑定事件

    xVariable3 = tk.StringVar()
    com3 = ttk.Combobox(master, textvariable=xVariable3, width=3)  # #创建下拉菜单
    # com.pack()  # #将下拉菜单绑定到窗体
    com3.place(x=260, y=50)
    com3["value"] = ("00","05","10","15","20","25","30","35","40","45","50","55")  # #给下拉菜单设定值
    com3.current(0)  # #设定下拉菜单的默认值为第2个

    def xFunc3(event):
        #print(com3.get())  # #获取选中的值方法1
        xVariable3.get() # #获取选中的值方法2

    com3.bind("<<ComboboxSelected>>", xFunc3)  # #给下拉菜单绑定事件

    # 首次打卡函数,无论何时启动打卡,都能在设置的打卡时间进行打卡,退卡时间进行退卡
    def start_time():
        now = datetime.datetime.now()  # 当前时间,即:程序启动的时间
        workon_time = com.get()+':'+com1.get()  # 打卡时间字符串
        output_1='当前打卡时间:'+workon_time+'\n'
        t2.insert(tk.INSERT, output_1)
        workon_time1 = datetime.datetime.strptime(workon_time, '%H:%M')  # 将打卡时间字符串转换成时间格式
        second = (workon_time1 - now).seconds  # 计算现在到打卡时间之间的秒数
        minsecond = second * 1000  # 转换成毫秒,供window.after使用
        h = minsecond / 3600000  # 转换成小时,供输出
        ts = str(h) + '小时后开始打卡\n'
        t2.insert(tk.INSERT, ts)  # 输出到t1

        workoff_time = com2.get()+':'+com3.get()
        output_2='当前退卡时间:'+workoff_time+'\n'
        t2.insert(tk.INSERT, output_2)
        workoff_time1 = datetime.datetime.strptime(workoff_time, '%H:%M')
        second1 = (workoff_time1 - now).seconds  # 现在到打卡时间之间的秒数
        minsecond1 = second1 * 1000
        h1 = minsecond1 / 3600000
        ts1 = str(h1) + '小时后开始退卡\n'
        t2.insert(tk.INSERT, ts1)

        master.after(minsecond, start_time1)  # second秒后执行循环打卡函数
        master.after(minsecond1, start_time2)  # second1秒后执行循环退卡函数

    # 循环打卡函数,每24小时执行一次
    def start_time1():
        ts = '打卡启动\n'
        t2.insert(tk.INSERT, ts)
        randomtimes()  # 执行一次随机打卡函数
        master.after(86400000, start_time1)  # 每24小时执行一次自己,实现循环

    # 循环退卡函数,每24小时执行一次
    def start_time2():
        ts = '退卡启动\n'
        t2.insert(tk.INSERT, ts)
        randomtimes1()  # 执行一次随机退卡函数
        master.after(86400000, start_time2)  # 每24小时执行一次自己,实现循环

    # 随机打卡函数,用于让打卡时间随机
    def randomtimes():
        s = random.randint(0, 360)  # 随机一个360秒内的秒数
        t2.insert(tk.INSERT, str(s) + '秒后开始打卡......\n')
        mins = s * 1000  # 转换成毫秒
        master.after(mins, work_on)  # mins毫秒后执行打卡函数

    # 随机退卡函数,用于让退卡时间随机
    def randomtimes1():
        s = random.randint(0, 360)
        t2.insert(tk.INSERT, str(s) + '秒后开始退卡......\n')
        mins = s * 1000
        master.after(mins, work_off)  # mins毫秒后执行退卡函数

    def get_rsa_result(content):
        """
        根据 模量与指数 生成公钥,并利用公钥对内容 rsa 加密返回结果
        :param e:指数
        :param n: 模量
        :param content:待加密字符串
        :return: 加密后结果
        """
        n = "8bcbceb956d3d6c0da8cd8847e50796eac0fb3d67d4901820fa85dcd8edbb30bd25966eb18223e1ace1308da181897df4559bf97cca6ae9a33a0baf6f53324334a385d2a7cbc186fb5070045080b6c948423e7ddcd795ac9eaa438317772f4a948409ecec92dfe222a10b4c327e8d0e494cc0aa42ebc786030a105da0637049d"
        e = "10001"
        e = int(e, 16)
        n = int(n, 16)

        pub_key = rsa.PublicKey(e=e, n=n)
        m = rsa.encrypt(content.encode(), pub_key)
        # print(m.hex())
        return m.hex()

    # 打卡函数,用于打卡
    def work_on():
        passd = get_rsa_result(psd)
        s = requests.session()
        headers = {'Host': 'e.xxxx.com',
                   'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0',
                   'Accept': 'application/json, text/java, */*; q=0.01',
                   'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
                   'Accept-Encoding': 'gzip, deflate',
                   'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
                   'X-Requested-With': 'XMLHttpRequest',
                   'Origin': 'http://e.xxxx.com',
                   'Connection': 'close',
                   'Referer': 'http://e.xxxx.com/portal/',
                   }
        postdata = {'lang': 'cn', 'userid': usr, 'pwd': passd, 'cmd': 'CLIENT_USER_LOGIN', 'sid': '',
                    'deviceType': 'pc', '_CACHE_LOGIN_TIME_': '1579162050273', 'pwdEncode': 'RSA', 'timeZone': '-8'}
        url = 'http://e.xxxx.com/portal/r/jd'
        rs = s.post(url, postdata, headers=headers)
        result = rs.text
        if 'error' not in result:
            sid = json.loads(result)['data']['sid']
            # print('Login sucessful:'+usr+':'+psd)
            work_url = 'http://e.xxxx.com/portal/r/jd?sid=' + sid + '&cmd=com.hrpaas.apps.atnd.sign'
            work_postdata = {'signtype': 1, 'type': 1}
            work_rs = s.post(work_url, work_postdata, headers=headers)
            if 'error' not in work_rs.text:
                now = time.strftime("%Y-%m-%d %H:%M:%S")
                output_sucessful = '打卡成功!'
                t2.insert(tk.INSERT, str(now) + ':')
                t2.insert(tk.INSERT, output_sucessful)
            elif 'WIFI' in work_rs.text:
                now = time.strftime("%Y-%m-%d %H:%M:%S")
                output_err = '打卡失败,你当前网络不在打卡范围\n'
                t2.insert(tk.INSERT, str(now) + ':')
                t2.insert(tk.INSERT, output_err)
            else:
                now = time.strftime("%Y-%m-%d %H:%M:%S")
                output_err1 = '打卡失败,未知原因\n'
                t2.insert(tk.INSERT, str(now) + ':')
                t2.insert(tk.INSERT, output_err1)
        else:
            now = time.strftime("%Y-%m-%d %H:%M:%S")
            ts = '账户异常\n'
            t2.insert(tk.INSERT, str(now) + ':')
            t2.insert(tk.INSERT, ts)

    # 退卡函数,用于退卡
    def work_off():
        passd = get_rsa_result(psd)
        s = requests.session()
        headers = {'Host': 'e.xxxx.com',
                   'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0',
                   'Accept': 'application/json, text/java, */*; q=0.01',
                   'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
                   'Accept-Encoding': 'gzip, deflate',
                   'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
                   'X-Requested-With': 'XMLHttpRequest',
                   'Origin': 'http://e.xxxx.com',
                   'Connection': 'close',
                   'Referer': 'http://e.xxxx.com/portal/',
                   }
        postdata = {'lang': 'cn', 'userid': usr, 'pwd': passd, 'cmd': 'CLIENT_USER_LOGIN', 'sid': '',
                    'deviceType': 'pc',
                    '_CACHE_LOGIN_TIME_': '1579162050273', 'pwdEncode': 'RSA', 'timeZone': '-8'}
        url = 'http://e.xxxx.com/portal/r/jd'
        rs = s.post(url, postdata, headers=headers)
        result = rs.text
        if 'error' not in result:
            sid = json.loads(result)['data']['sid']
            # print('Login sucessful:'+usr+':'+psd)
            work_url = 'http://e.xxxx.com/portal/r/jd?sid=' + sid + '&cmd=com.hrpaas.apps.atnd.sign'
            work_postdata = {'signtype': 1, 'type': 2}
            work_rs = s.post(work_url, work_postdata, headers=headers)
            if 'error' not in work_rs.text:
                now = time.strftime("%Y-%m-%d %H:%M:%S")
                output_sucessful = '退卡成功!'
                t2.insert(tk.INSERT, str(now) + ':')
                t2.insert(tk.INSERT, output_sucessful)
            elif 'WIFI' in work_rs.text:
                now = time.strftime("%Y-%m-%d %H:%M:%S")
                output_err = '退卡失败,你当前网络不在打卡范围\n'
                t2.insert(tk.INSERT, str(now) + ':')
                t2.insert(tk.INSERT, output_err)
            else:
                now = time.strftime("%Y-%m-%d %H:%M:%S")
                output_err1 = '退卡失败,未知原因\n'
                t2.insert(tk.INSERT, str(now) + ':')
                t2.insert(tk.INSERT, output_err1)
        else:
            now = time.strftime("%Y-%m-%d %H:%M:%S")
            ts = '账户异常\n'
            t2.insert(tk.INSERT, str(now) + ':')
            t2.insert(tk.INSERT, ts)

    b1 = tk.Button(interface1, text='启 动', width=10, height=1, command=start_time)
    b1.place(x=130, y=80)

    t2 = tk.Text(interface1, bg='green', fg='white', width=47, height=14)
    # 说明: bg为背景,fg为字体颜色,font为字体,width为长,height为高,这里的长和高是字符的长和高,比如height=2,就是标签有2个字符这么高
    t2.place(x=10, y=120)

    output_0 = '登录成功!请设置打卡时间和退卡时间\n'
    t2.insert(tk.INSERT, output_0)

    l3 = tk.Label(interface1, text='作者:沙漠网管', font=('Arial', 10))
    l3.place(x=130, y=320)

if __name__=='__main__':
    root = tk.Tk()
    basedesk(root)
    root.mainloop()

使用:
使用pyinstaller打包成exe直接双击执行即可使用:

pyinstaller -F -w autologin.py
  • 21
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值