Python实现i人事自动打卡的示例代码
本文介绍了如何利用Python结合Fiddler抓包工具与Linux crontab定时任务,实现i人事应用的自动签到与签退功能。通过配置模拟器代理、捕获API接口参数,编写Python脚本模拟POST请求,并设置定时执行策略,旨在解决人工打卡易遗漏的问题。
i人事自动打卡实现思路
公司目前使用的考勤系统是i人事,由于个人记忆力不佳,经常忘记签到或签退,即便设置了闹钟也时常遗漏,导致再次被上级批评。因此,我决定抓取相关的签到接口,并借助Linux系统的crontab服务来实现自动化的签到与签退操作。
环境配置与Fiddler安装
环境配置
本文选用Fiddler作为HTTP调试代理工具进行抓包,该工具以代理服务器形式监听网络数据流。未选择Wireshark的原因在于对其筛选器不够熟悉,且本次操作使用模拟器进行,手机应用后台流量较大,使用代理服务器方式更便于分析。
安装Fiddler
首先安装Fiddler(官网地址),安装完成后需安装fiddlercertmaker证书生成工具(官网地址)。
Fiddler配置
如图所示,启动Fiddler后,依次选择Tools和Fiddler Options,勾选图中所示选项,配置完成后点击OK保存并重启Fiddler。
再次打开该选项卡,点击Action按钮生成证书至桌面(文件名为FiddlerRoot.cer)。
将该证书文件上传至模拟器中即可。
模拟器代理与证书配置
模拟器配置
记录Windows当前网卡的IP地址以备后用。
打开模拟器,在系统设置中选择“安全”,点击“从SD卡安装”,选择之前上传的证书进行安装(过程中需设置屏保密码,按要求设置即可)。
在模拟器内选择WiFi连接,长按当前WiFi,选择“修改网络”,勾选“手动配置代理”,地址填写之前记录的Windows本地IP,端口设置为8888,保存后重启模拟器。
Fiddler抓包与接口分析
开始抓包
配置过滤器
启动Fiddler并打开模拟器后,Fiddler会监听到大量流量信息。为了便于查找目标请求,需使用过滤器:在Fiddler界面右侧选择“Filters”并勾选“Use Filters”,在“Hosts”项目中选择“Show only the following Hosts”,填入“www.ihr360.com”以过滤掉非i人事域名的流量;同时在“Request Headers”中勾选“Show only if URL contains”,填入“gateway/attendance/aggregate/attendance/api/sign/doSign”,点击右上角Actions并选择“Run Filterset now”以生效过滤器。最后,在Fiddler左侧流量信息栏中使用Ctrl+X清除当前所有流量信息。

模拟器签到
将模拟器的定位功能设置为目标打卡位置,打开i人事应用,点击考勤打卡进行签到。此时Fiddler中会出现一条监听的请求,双击打开查看,如图所示。
可以看到,实际上打卡签到动作就是一条POST请求。我们了解了这条POST请求的基本内容后就可以利用Python的requests模块来模拟提交了。
Python模拟请求与定时任务
模拟请求
模拟POST请求很简单,这里就不多说,直接贴代码(很烂=.=! ,能用就行啦…勿喷…):
#!/usr/bin/env python3
# www.iots.vip
# Alliot
# 2020-1-8
import requests
import json
import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr
from time import strftime, localtime
# 忽略 requests 请求认证警告
requests.packages.urllib3.disable_warnings()
# 邮件设置
server = 'smtp.163.com'
port = '25'
sender = '发件人邮箱'
passwd = '密码(授权码)'
receiver = '收件人'
# i 人事签到接口地址
url = "https://www.ihr360.com/gateway/attendance/aggregate/attendance/api/sign/doSign"
# 抓包签到请求头
headersValue = {
'Cookie': 'SESSION=XXXXXXXXXXXXXX; Path=/; HttpOnly',
'accept': 'application/json;charset=UTF-8',
'appKey': 'com.irenshi.personneltreasure',
'appVersion': 'XXXX',
'osVersion': 'XXXX',
'udid': 'XXXXXX',
'user-agent': 'IRENSHI_APP_AGENT',
'os': 'Android',
'irenshilocale': 'zh_CN',
'Content-Type': 'application/json; charset=utf-8',
'Content-Length': '272',
'Host': 'www.ihr360.com',
'Connection': 'Keep-Alive',
'Accept-Encoding': 'gzip',
}
# 抓包请求 json
jsonValue = {
"deviceToken": " ",
"deviceType": "NORMAL",
"latitude": XXX,
"locationName": "XXX",
"longitude": XXX,
"phoneName": "MI6",
"signSource": "APP",
"wifiMac": "XXX",
"wifiName": "Alliot",
}
# 签到方法
def doSign(url, jsonValue, headersValue):
r = requests.post(url, json=jsonValue, headers=headersValue, verify=False)
global results
results = json.loads(r.text)
print(strftime("%Y-%m-%d %H:%M:%S", localtime()))
return results
# 邮件提醒方法
def sendMail(server, port, sender, passwd, msg):
smtp = smtplib.SMTP()
smtp.connect(server, port)
smtp.login(sender, passwd)
smtp.sendmail(msg['From'], msg['To'], msg.as_string())
smtp.quit()
print('邮件发送成功email has send out !')
def newMail(status):
msg = MIMEText(str(results), 'plain', 'utf-8')
msg['From'] = formataddr(["AlliotSigner", sender])
msg['To'] = formataddr(["Alliot", receiver])
if status == None:
msg['Subject'] = '打卡失败-_-!'
print("打卡失败")
else:
msg['Subject'] = '自动打卡成功'
print("打卡成功")
sendMail(server, port, sender, passwd, msg)
# 签到并邮件通知结果,不用通知则改为 doSign(url, jsonValue, headersValue) 即可
newMail(doSign(url, jsonValue, headersValue)["data"])
# doSign(url, jsonValue, headersValue)
修改其中的配置为上文抓到的数据即可(这里注意, headersValue 请求头为字典格式, jsonValue 则为 Json 格式,执行报错的时候检查一下是否是格式错误。)
上传到服务器中,执行:
python3 ihr.py # 你的文件名
执行后,打开 i 人事查看是否成功产生一次签到记录,成功即可添加进计划任务。
定时执行
利用 crontab 来实现自动执行。关于 crontab 的具体使用,可见 Linux下crontab的使用与注意事项 | Alliot's blog
我是定义每周工作日的 8 点 18 点打卡,crontab 配置为:
0 8,18 * * mon,tue,wed,thu,fri,sat /usr/bin/python3 /alliot/ihr.py>>/alliot/ihr_log.txt
后记
整个流程很简单粗暴,其实一般后台都是能看出来的,因为每次的签到位置都是一样,所以如果想要逼真一点,可以在请求中经纬度、位置名里使用范围的随机数等等… 不过,还是那句话: 可以,但没必要。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









