python实现oa系统_利用Python实现某OA系统的自动定位功能
本文介绍了笔者通过python程序实现某OA系统自动考勤打卡功能及相关逻辑原理的解析。
需求分析
疫情期间,笔者所在公司使用某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():程序入口函数,获取用户输入```
代码解析
通过上面的介绍,我们已经大概了解整个程序的运行逻辑,下面对部分关键代码进行解析(部分常规代码有省略):
```python
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®isterSourceUrl=®isterSource=®isterDataSource=&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,记录形式是这样的:
, , ]>
因此这里利用正则匹配出我们所需要的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
#以上代码通过在返回报文中查找成功和失败的字符,作为考勤是否成功的判断依据,并输出到终端提示用户
..........
python
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()
python
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系统自动定位内容请搜索python博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持python博客!
python实现oa系统_利用Python实现某OA系统的自动定位功能相关推荐
- 基于python的排课表系统_利用python爬取广西科技大学教务管理信息系统班级课表...
操作环境 python 3.6.1 pycharm 5.0.3 WampServer 3.0.6 windows 8(64位) 特点 1.中途退出程序或者断网之后重连再次运行不会抓取到重复的课程表 2 ...
- python制作电脑软件_利用PYTHON制作桌面版爬虫软件(一)
抱歉,对长沙房地产数据的挖掘与分析[三],想了蛮久,觉得对自己的分析结果不是很理想.等我完善好了,我再发出来吧.今天继续开启新的一专题.主要讲解如何用PYTHON实现简单的桌面软件的制作. 题外话,我 ...
- python post请求 上传图片_利用python模拟实现POST请求提交图片的方法
本文主要给大家介绍的是关于利用python模拟实现POST请求提交图片的方法,分享出来供大家参考学习,下面来一看看详细的介绍: 使用requests来模拟HTTP请求本来是一件非常轻松的事情,比如上传 ...
- python自定义函数画图_利用Python绘图和可视化(长文慎入)
Python有许多可视化工具,但是我主要讲解matplotlib(http://matplotlib.sourceforge.net).此外,还可以利用诸如d3.js(http://d3js.org/ ...
- python如何自动打印_利用Python每天自动打印练习题
在日常教学工作中,我几乎每天都会给班上的每位同学打印一份口算练习题.为了防止出现抄袭的现象,给每位同学的练习题都不相同. 通过网上下载的一个小软件自动生成的练习题. 之前的操作是通过网上下载的软件,自 ...
- python实现邮件客户端_利用python实现简单的邮件发送客户端示例
脚本过于简单,供学习和参考.主要了解一下smtplib库的使用和超时机制的实现.使用signal.alarm实现超时机制. #!/usr/bin/env python # -*- coding: ut ...
- python制作图片墙_利用python生成照片墙的示例代码
PIL(Python Image Library)是python的第三方图像处理库,但是由于其强大的功能与众多的使用人数,几乎已经被认为是python官方图像处理库了.其官方主页为:PIL. PIL历 ...
- python过滤敏感词汇_利用Python正则表达式过滤敏感词的方法
利用Python正则表达式过滤敏感词的方法 问题描述:很多网站会对用户发帖内容进行一定的检查,并自动把敏感词修改为特定的字符. 技术要点: 1)Python正则表达式模块re的sub()函数: 2)在 ...
- 利用python进行数据分析数据_利用Python进行数据分析
1.注释以及在Subplot上绘图 除标准的图表对象之外,你可能还希望绘制一些自定义的注释(比如文本.箭头或其他图形等). 注释可以通过text.arrow和annotate等函数进行添加.text可 ...
- python处理nc数据_利用python如何处理nc数据详解
利用python如何处理nc数据详解 来源:中文源码网 浏览: 次 日期:2018年9月2日 [下载文档: 利用python如何处理nc数据详解.txt ] (友情提示:右键点上行txt ...
最新文章
- python 3.7.732位安装步骤_python安装教程(Windows系统,python3.7为例)
- 自定义Scrollview--实现仿淘宝Toolbar透明度渐变效果
- python基础教程:函数作用域
- [PyJs系列介绍]三、编译与上线
- 蠕变断裂 ansys_如何避免范围蠕变,以及其他软件设计课程的辛苦学习方法
- 安装erlang没有bin文件夹_RabbitMQ安装教程
- php sockets有什么用,PHP中Sockets与流有什么关系啊!!!!!
- kotlin java 知乎_Kotlin入门第一课:从对比Java开始
- [2018.05.05 T1] 互质
- 安卓手机左右声道调节应用下载_闪电全能格式转换器下载_闪电全能格式转换器官方下载[转换工具]...
- mysql awr报告怎么看,OracleAWR报告查看分析
- 针对测试人员,这些业务安全漏洞你是否会测?
- 能上msn,icq等聊天的web工具meebo.com
- ETL为什么经常变成ELT甚至LET?
- 数据库篇-mysql主备搭建
- linux添加ip白名单_centOS7 下利用iptables配置IP地址白名单的方法
- Centos7部署个人wiki(bookstack)踩坑版
- 深度盘点:Python 使用和高性能技巧总结
- 常见分布式ID生成方案
- 计算机毕业设计Java智能停车场管理系统(源码+系统+mysql数据库+lw文档)
热门文章
- jav学习笔记-String源码分析
- LPVOID傳遞參數的問題
- hive-使用开窗函数实现百分比、topN、前百分比
- 计算机中所占百分数用哪个函数,Excel中Percentrank函数的使用-计算所占百分比
- ARM 电源管理 4种模式
- 1330_硬件测试中的BCI测试
- 计算机课件制作技能,PPT技能制作大比拼
- 关于html中reset图片,关于html5中form表单的reset几种用法
- 工作拾忆 一年C++经验小记
- android手机内存越来越小,手机内存越来越小怎么办 手机内存清理方法【步骤】...