1. 程式人生 > 程式設計 >Python實現i人事自動打卡的示例程式碼

Python實現i人事自動打卡的示例程式碼

我司使用的打卡軟體是 i 人事,不過我這記性,經常漏了打卡簽退,定了鬧鐘都會忘,今天又被老大屌了。於是準備抓一下籤到介面,利用 crontab 來實現自動簽到簽退。

環境配置

這裡使用的是 Fiddler 進行抓包,Fiddler 是一個 HTTP 除錯代理工具,以代理伺服器的形式實現對網路資料流的監聽。之所以沒有用 Wireshark,一是因為我不是很熟悉 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 介面右側,選擇 “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 模組來模擬提交了。

模擬請求

模擬 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,msg)
# 簽到並郵件通知結果,不用通知則改為 doSign(url,headersValue) 即可
newMail(doSign(url,headersValue)["data"])
# doSign(url,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

後記

整個流程很簡單粗暴,其實一般後臺都是能看出來的,因為每次的簽到位置都是一樣,所以如果想要逼真一點,可以在請求中經緯度、位置名裡使用範圍的隨機數等等… 不過,還是那句話: 可以,但沒必要。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。