利用Python实现某OA系统的自动定位功能

本文介绍了笔者通过python程序实现某OA系统自动考勤打卡功能及相关逻辑原理的解析。

Github: https://github.com/cahi1l1yn/eChecker

需求分析

疫情期间,笔者所在公司使用某OA系统的考勤功能代替原来的刷脸考勤,结果导致很多人经常忘记打卡,于是笔者寻思着能不能写个程序实现自动考勤,希望实现的主要功能是:指定用户名密码登录和指定时间签到签退,扩展功能是:自定义签到和签退的IP或定位地址。

系统逻辑分析

为了通过python实现上述功能,首先需要人工访问系统进行相关的操作,并抓包分析请求和返回数据,弄清逻辑原理,下面介绍分析过程:

登录

访问OA系统登录页面,点击输入登录信息后截取登录数据包,分析发现登录接口除了验证用户名和密码外,还会验证下图红框所示的cookie和token参数。因此我们需要找到这两个参数值从哪里获取。

重新访问登录页面并抓取返回包,首先从返回包头部看到了JSESSIONID参数,而另一个lt参数则在返回页面的源码中。

弄清楚这两个参数的来源后,我们重新回到登录页面提交登录请求,获取并记录下会话cookie。

考勤

登录账号后,进入考勤模块进行打工并截取数据包,可以看出程序是通过向考勤接口提交参数值为CHECKIN和CHECKOUT的json字符串以实现签到和签退。

另外可以看到请求包中携带了好几个cookie参数,经过不断的测试排除后,最终确定WEBID、JSESSIONID和ETEAMSID这三个为关键cookie,其余几个都可以忽略。

自定义考勤地址

上述测试过程是PC端的,由于其中并没有涉及到地址的参数,因此转到APP端进行测试。截取APP端的考勤请求包,可以看到checkaddress参数就是考勤定位地址。

笔者尝试在PC端的考勤请求参数中插入checkaddress,从响应包中可以看出已经成功使用该参数自定义考勤地址进行考勤,同时这里如果再加入经纬度参数的话,即可高度模拟定位考勤。

值得关注的是,笔者分析发现当考勤请求携带了PC端UA时,服务端会将客户端识别为PC端,此时不会处理checkaddress参数,签到地址就是客户端的真实IP地址。当考勤请求携带移动端UA或者pythonUA时,服务端会将客户端识别为移动端且处理checkaddress参数,此时就可以实现自定义考勤地址,包括IP地址和地理位置。

逻辑梳理

通过上述操作后,笔者已经了解到登录接口和考勤接口的逻辑和请求形式,下面简单梳理相关流程,这个流程也就是后续编写程序主要的逻辑依据:

1.【用户访问登录页面】
       ||
       \/
2.【登录页面返回一个cookie(JSESSIONID)和token(lt)】
       ||
       \/
3.【用户携带cookie像登录接口提交token、用户名和密码】
       ||
       \/
4.【登录接口验证成功后返回会话cookie(ETEAMSID\JSESSIONID\)】
       ||
       \/
5.【用户携带会话cookie向考勤接口提交签到/签退请求】

功能实现

这里先回顾一下本程序实现需求是:指定用户名密码登录和指定时间签到签退。通过上述逻辑梳理,已经可以实现指定用户和密码登录已经签到签退,另外还需要实现的就是指定时间,下面我们加入指定时间相关的功能再次梳理python程序的主要功能逻辑:

1.【输入用户名、密码、签到签退时间运行程序】
       ||
       \/
2.【登录系统获取会话cookie】
       ||
       \/
3.【程序获取本地时间】
       ||
       \/
4.【程序比对本地时间和用户设定时间】
       ||
       \/
5.【在指定时间携带会话cookie进行考勤】

程序结构

梳理出程序主要功能逻辑后,开始定义函数分别实现上述主要功能,下面列出程序的主要函数结构:

def get_cookie(user,passwd):登录系统,获取会话cookie,该函数实现了[逻辑梳理]中的第2-4步
def keep_session():维持会话cookie有效性,因cookie长期不活跃会失效,因此通过此函数访问系统以维持cookie,如果cookie已经失效,则会调用get_cookie函数重新登录获取cookie
def check_in():签到模块,携带cookie向考勤接口提交CHECKIN
def check_out():签退模块,携带cookie向考勤接口提交CHECKOUT
def get_position():定位模块,根据用户输入的地理位置获取经纬度
def check_time():获取本地时间并于用户设定时间作比对,触发考勤模块和会话维持模块
def main():程序入口函数,获取用户输入

代码解析

通过上面的介绍,我们已经大概了解整个程序的运行逻辑,下面对部分关键代码进行解析(部分常规代码有省略):

def get_cookie(user,passwd):
 ...........
 token = re.search(r'LT\S+cn',html).group()
 #urllib访问登录页面后,从页面中获取lt参数值,即token
 pcookie = re.search(r'JSESSIONID=\S+',str(pres.info().headers)).group()
 #访问登录页面后,从返回包头部中获取cookie,后续提交登录请求时需要携带该cookie
 data ='lt='+token+'&execution=e1.2&j_pcClient=&_eventId=submit&isApplyed=false&registerSourceUrl=&registerSource=&registerDataSource=&username='+user+'&password='+passwd
 #组合token和用户输入的登录信息,用于组成登录请求
 req = urllib2.Request(lurl)
 cj = cookielib.CookieJar()
 opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
 #通过cookiejar记录登录成功后页面返回的会话cookie
 opener.addheaders = [('Cookie',pcookie)]
 #在登录请求包头中加入一开始获取到的cookie
 try:
  res = opener.open(lurl,data=data,timeout=10)
 except urllib2.URLError:
  print '[ERROR]Urlllib error, retry later'
 try:
  cookie = re.search(r'ETEAMSID=\w+',str(cj)).group()+';'+re.search(r'JSESSIONID=\w+',str(cj)).group()+';'+re.search(r'WEBID=\w+',str(cj)).group()
 #到这一步已经登录成功,cookiejar已经记录了会话cookie,记录形式是这样的:
 <CookieJar[<Cookie BIDUPSID=B681378758CB3586029EBFFFF16FBDE2 for .baidu.com/>, <Cookie PSTM=1532404690 for .baidu.com/>, <Cookie BD_NOT_HTTPS=1 for www.baidu.com/>]>
 因此这里利用正则匹配出我们所需要的3个cookie值
  print '[INFO]Login succeed, your cookie is:'+cookie
 ...........
def check_in():
 ............
 req = urllib2.Request(curl)
 req.add_header("Cookie",cookie)
 req.add_header("Content-Type","application/json")
 if stat == '0':
  data = json.dumps({"type":"CHECKOUT","checkAddress":addr,"longitude":longi,'latitude':lati})
 #当用户自定义了考勤地址时,且成功获取到经纬度信息时,提交的请求中加入了地理位置和经纬度参数,服务端默认将urllib的UA识别为移动端,故会记录用户提交的地理信息,完美模拟定位考勤效果
 elif stat == '1':
  data = json.dumps({"type":"CHECKOUT","checkAddress":addr})
 #当用户自定义了考勤地址时,但未成功获取到经纬度信息时,提交的请求中只加入地理位
 elif stat =='2':
  req.add_header('User-Agent',ua)
  data = json.dumps({"type":"CHECKOUT"})
 #当用户未自定义考勤地址时,提交的请求按PC端原始格式,且此处需要加入自定义的PC端UA,否则服务端会将签到地址记录为空值
 try:
  res = urllib2.urlopen(req,data=data,timeout=5).read()
  smsg = res.find('签到成功')
  fmsg = res.find('签到失败')
  if smsg > -1:
   print '[INFO]'+time.strftime('%Y-%m-%d_%H:%M',time.localtime())+' Checkin succeed'
  elif fmsg > -1:
   print '[WARNING]'+time.strftime('%Y-%m-%d_%H:%M',time.localtime())+' Checkin fail:'+res
 #以上代码通过在返回报文中查找成功和失败的字符,作为考勤是否成功的判断依据,并输出到终端提示用户
 ..........
def check_time():
 while True:
  ltime = time.strftime('%H:%M',time.localtime()).lstrip('0')
  day = time.strftime('%a',time.localtime())
  #获取当前的时间,lstrip去0是为了时针为0-9的个位数时进行格式统一
  ..........
  if ltime == '4:30':
   keep_session()
   time.sleep(60)
  #由于会话cookie在一定时间后(貌似是十几个小时)会失效,因此设定在凌晨调用keepsession()维持cookie
  elif ltime == intime.lstrip('0') and day not in ('Sat','Sun'):
  #比对本地时间与用户输入时间,且判断是否周末
   keep_session()
  #进行考勤前,再次检验cookie是否有效
   rnd = random.randint(0,600)
   print '[INFO]Checkin after ' + str(int(rnd)/60) + ' Min ' + str(int(rnd)%60) + ' Sec'
   time.sleep(int(rnd))
   check_in()
  #为了避免用户设定一个时间后,程序每天都在同一时间点考勤,这里结合sleep和random实现在用户设定时间上正向浮动随机时间进行考勤
   time.sleep(60)
  ........
  ........
  check_time()
def get_position(addr):
 global longi
 global lati
 url = 'http://api.map.baidu.com/geocoding/v3/?address='+addr+'&output=json&ak='+api_key+'&callback=showLocation'
 html = urllib2.urlopen(url.encode('utf-8')).read()
 longi = re.search(r'lng":\d+.\d+',html).group().lstrip('lng":')
 lati = re.search(r'lat":\d+.\d+',html).group().lstrip('lat":')
 #调用百度地图API获取经纬度信息,使用encode('utf-8')处理url可以避免中文乱码问题(需要注册APIKEY)

运行效果

总结

本文分享了笔者利用python编写某OA系统自动考勤程序的过程,包括对系统逻辑的分析、程序结构的介绍和关键代码的解析等内容。

程序最终实现了用户自定义考勤时间、地址,并自动根据地址获取经纬度(如地址为IP地址则不获取),每天在指定时间以上述自定义信息进行考勤。

注:考勤地址可自定义的漏洞已经上报。

到此这篇关于利用Python实现某OA系统的自动定位功能的文章就介绍到这了,更多相关python实现OA系统自动定位内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 基于python全局设置id 自动化测试元素定位过程解析

    背景: 在自动化化测试过程中,不方便准确获取页面的元素,或者在重构过程中方法修改造成元素层级改变,因此通过设置id准备定位. 一.python准备工作: 功能:用自动化的方式进行批量处理. 比如,你想要在大量的文本文件中执行查找/替换,或者以复杂的方式对大量的图片进行重命名和整理. 语法用例: #!/usr/bin/python //脚本语言的第一行,只对 Linux/Unix 用户适用,用来指定本脚本用什么解释器来执行,即:调用 /usr/bin 下的 python 解释器,推荐使用#!/us

  • selenium+python自动化测试之页面元素定位

    上一篇博客selenium+python自动化测试(二)–使用webdriver操作浏览器讲解了使用webdriver操作浏览器的各种方法,可以实现对浏览器进行操作了,接下来就是对浏览器页面中的元素进行操作,操作页面元素,首先要找到操作的元素,对元素进行定位 查看页面源码 要定位页面元素,需要找到页面的源码,IE浏览器中,打开页面后,在页面上点击鼠标右键,会有"查看源代码"的选项,点击后就会进入页面源码页面,在这里就可以找到页面的所有元素 使用Chrome浏览器打开页面后,在浏览器的地

  • python3 selenium自动化测试 强大的CSS定位方法

    ccs的优点:css相对xpath语法比xpath简洁,定位速度比xpath快 css的缺点:css不支持用逻辑运算符来定位,而xpath支持.css定位语法形式多样,相对xpath比较难记. css定位建议多用,这个定位方式很强大,定位速度快且准确度高.至于难记,用熟了就好了,对勤快的人来说,这不是问题. CSS_selector常用符号: # 表示id . 表示class > 表示子元素,层级 1.通过id属性定位: find_element_by_css_selector("#id的

  • python3 selenium自动化 下拉框定位的例子

    我们在做web UI自动化时,经常会碰到下拉框,如下图: 所上图,下拉框的源代码如下: <html1> <head></head> <body> <select id="fruit" name="水果" style="width:100px;"> <option value ="0">苹果</option> <option value =

  • 利用Python实现某OA系统的自动定位功能

    本文介绍了笔者通过python程序实现某OA系统自动考勤打卡功能及相关逻辑原理的解析. Github: https://github.com/cahi1l1yn/eChecker 需求分析 疫情期间,笔者所在公司使用某OA系统的考勤功能代替原来的刷脸考勤,结果导致很多人经常忘记打卡,于是笔者寻思着能不能写个程序实现自动考勤,希望实现的主要功能是:指定用户名密码登录和指定时间签到签退,扩展功能是:自定义签到和签退的IP或定位地址. 系统逻辑分析 为了通过python实现上述功能,首先需要人工访问系

  • 利用python实现微信头像加红色数字功能

    通过Python实现将你的 QQ 头像(或者微博头像)右上角加上红色的数字,类似于微信未读信息数量那种提示效果. 类似于图中效果 实现过程: 准备两张图片如下:   使用PIL图像处理库,导入moudle from PIL import Image from PIL import ImageFont from PIL import ImageDraw def white_to_transparent(img): img=img.convert('RGBA') #返回一个转换后的图像的副本 dat

  • 利用python实现短信和电话提醒功能的例子

    有时候,我们需要程序帮我们自动检测某些事件的发生 这个需求是广泛存在的 因此,这里整理了利用python实现短信和电话提醒功能的方法 主要需要完成以下4个步骤: - 安装核心库:twilio - 注册账号及配置 - 发送短信示例 - 电话提醒示例 twilio twilio是我们需要的核心库,我们要利用其提供的api完成所需的功能 首先安装twilio模块(我使用的是python3) pip3 install twilio 注册账号及配置 首先访问https://www.twilio.com/并

  • 利用Python实现QQ实时到账免签支付功能

    原创 转载请注明出处 核心部分:解决QQ的登录验证问题 主要利用python的selenium库和QQ的快速登录实现登录网页 再利用抓到的json来输出今日的订单情况 直接上代码 import requests import time import os from selenium import webdriver import sys import shutil import json ''' 注意:要实现QQ钱包实时到账 需要在服务器上登录QQ 且需要在服务器上配置python3 chrom

  • 利用python微信库itchat实现微信自动回复功能

    前言 在论坛上看到了用Python登录微信并实现自动签到,才了解到一个新的Python库: itchat 利用Python 微信库itchat,可以实现自动回复等多种功能,好玩到根本停不下来啊,尤其是调戏调戏不懂计算机的,特别有成就感,哈哈!! 代码如下: #coding=utf8 import requests import itchat KEY = '8edce3ce905a4c1dbb965e6b35c3834d' def get_response(msg): apiUrl = 'http

  • 利用python实现凯撒密码加解密功能

    凯撒密码介绍 凯撒密码是一种非常古老的加密方法,相传当年凯撒大地行军打仗时为了保证自己的命令不被敌军知道,就使用这种特殊的方法进行通信,以确保信息传递的安全.他的原理很简单,说到底就是字母于字母之间的替换. 实验目的 应用Python程序设计语言的相关知识,理解并实现凯撒密码加解密过程. 实验内容 任务1:运行import this, 观察代码运行结果:查看this.py源文件(可以在Python安装目录下的Lib文件夹下找到),分析它的原理. 任务2:实现凯撒密码加解密过程. 实验环境 Pyt

  • 利用python求解物理学中的双弹簧质能系统详解

    前言 本文主要给大家介绍了关于利用python求解物理学中双弹簧质能系统的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 物理的模型如下: 在这个系统里有两个物体,它们的质量分别是m1和m2,被两个弹簧连接在一起,伸缩系统为k1和k2,左端固定.假定没有外力时,两个弹簧的长度为L1和L2. 由于两物体有重力,那么在平面上形成摩擦力,那么摩擦系数分别为b1和b2.所以可以把微分方程写成这样: 这是一个二阶的微分方程,为了使用python来求解,需要把它转换为一阶微分方程

  • 利用python、tensorflow、opencv、pyqt5实现人脸实时签到系统

    基于python opencv人脸识别的签到系统前言先看下效果实现的功能开始准备页面的构建功能实现代码部分总结 前言 一个基于opencv人脸识别和TensorFlow进行模型训练的人脸实时签到系统,作者某二本大学里的末流学生,写于2019/09/,python学习期间. 今年7月份开始接触python的,最近闲着无事就开始做了这个人脸识别的系统,一开始的话就想着简单的弄下,就去了百度智能云用的api接口实现的,写完以后我就想为什么我不自己写一个人脸识别签到,不去调用百度api接口,然后就诞生了

  • 利用Python Django实现简单博客系统

    第一节 - 基础 1. 简单的导览图,学会不迷路 对 Django 的评价:借用李清照的<鹧鸪天 桂花>来表达, 暗淡轻黄体性柔.情疏迹远只香留.何须浅碧深红色,自是花中第一流. 梅定妒,菊应羞.画阑开处冠中秋.骚人可煞无情思,何事当年不见收. Django makes it easier to build better Web apps more quickly and with less code. 容易上手,开发速度快 囊括了网站开发中的用户管理,内容管理,网站地图,RSS等常用的插件

  • 利用Python制作一个简单的天气播报系统

    目录 前言 工具 天气数据来源 代码实现 总结 前言 大家好,我是辣条 相信大家都能感觉到最近天气的多变,好几次出门半路天气转变.辣条也深受其扰,直接给我整感冒,就差被隔离起来了,既然天气我没法做主,那不如用python整个天气爬虫来获取天气情况.这样也好可以进行一个提前预防 工具 python3.7 pycharm pyttsx3:语音播报库 天气数据来源 找寻一个天气网站 比如说我们要查询某地的天气,在输入地名后就能看到结果. 我们可以看到网站的url会有变化: 每个城市的天气信息url就是

随机推荐