python 读取钉钉考勤数据
之前通过python读取钉钉考勤数据,在网上查了很多资源,也有很多完整的代码,但实际运行情况并不好,所以这次把在网上踩得坑着重讲解一下
整体代码如下
# -*- coding: utf-8 -*-
import dingtalka.api
import pandas as pd
import datetime as dt
import numpy as np
import pymysql
def getaccseetoken():
request = dingtalka.api.OapiGettokenRequest("https://oapi.dingtalk.com/gettoken")
request.appkey="appkey"
request.appsecret="appsecret"
f = request.getResponse()
access_token = f['access_token']
print(access_token)
return access_token
def get_userid_pro(access_token):
user_dept=[] #获部门下所有的部门节点
userid_name=[] #获取部门下所有人员id信息
userid_id=[]
request= dingtalka.api.OapiV2DepartmentListsubidRequest("https://oapi.dingtalk.com/topapi/v2/department/listsubid")
request.dept_id='XXXXX' #获取优先级最大的部门节点
dept_idmain = request.getResponse(access_token) #获取到部门节点下所有部门节点
userid = list(dept_idmain['result']['dept_id_list'])
user_dept.extend(userid)
for dept in userid:
request.dept_id = dept
dept_idmain = request.getResponse(access_token)
userid = list(dept_idmain['result']['dept_id_list'])
user_dept.extend(userid) # 获取部门下所有的部门节点,后续根据该节点读取部门人员id信息
while len(userid)!=0:
for j in userid:
request.dept_id = j
dept_idmain1 = request.getResponse(access_token)
userid1 = list(dept_idmain1['result']['dept_id_list'])
user_dept.extend(userid1)
userid=userid1
req = dingtalka.api.OapiV2UserListRequest("https://oapi.dingtalk.com/topapi/v2/user/list")
req.cursor = 0
req.size = 30
req.order_field = "entry_asc"
req.contain_access_limit =False
req.language = "zh_CN"
for i in user_dept:
req.dept_id = i
g = req.getResponse(access_token)
for j in g['result']['list']:
value=(j["userid"],j["dept_id_list"][0],j["name"])
value1=j["userid"]
userid_name.append(value)
userid_id.append(value1)
return userid_name,userid_id
def get_attendence_listrecord(userid, access_token, day):
# 获取打卡详情
request = dingtalka.api.OapiAttendanceListRecordRequest('https://oapi.dingtalk.com/attendance/list')
request.workDateFrom = str(dt.datetime.now() - day * dt.timedelta(days=1))
request.workDateTo = str(dt.datetime.now())
request.userIdList = userid
request.offset = 0
request.limit = 50
f = request.getResponse(access_token)
h = []
h.append(f)
while ('hasMore',True) in f.items(): #判断是否有更多数值
request.offset = request.offset+request.limit
f = request.getResponse(access_token)
h.append(f)
return h
def get_value(userid_in, access,days):
l = []
users = []
if len(userid_in)>50:
start = 0
end = 49
while end<len(userid_in):
users.append(userid_in[start:end])
start +=49
end = start+50
users.append(userid_in[start:end])
else:
users.append(userid_in[0:len(userid_in)])
for userid_in_in in users:
reponse = get_attendence_listrecord(userid_in_in, access, day=days)
for i in range(len(reponse)):
for respose in reponse[i]['recordresult']:
if respose['sourceType'] != 'SYSTEM':
value = (
respose['userId'], respose['checkType'], str(dt.datetime.fromtimestamp(int(respose['userCheckTime']) / 1000)),respose['locationResult'])
l.append(value)
return l
db = pymysql.connect(
host='IP位置',
port=端口号,
user='账号',
password='密码',
db='数据库名称',
charset="utf8")
cursor = db.cursor()
def insert_username(access_token):
query = """insert ignore into api_test_user (userid, dept_id,name
) values (%s,%s,%s)"""
value = get_userid_pro(access_token)
for record in value:
cursor.execute(query, record)
db.commit()
def insert(userid, access_token,days):
query = """insert ignore into api_test (userid, duty,time,type
) values (%s,%s,%s,%s)"""
value = get_value(userid, access_token,days)
for record in value:
cursor.execute(query, record)
db.commit()
if __name__ == '__main__':
access_token=getaccseetoken()
useridname,userid=get_userid_pro(access_token)
days=4 #4天前到目前时间的打卡考勤,时间不能超过7天
l = get_value(userid, access_token,days)
insert(userid, access_token,days)
接下来进行步骤拆解
获取accsstoken
首先钉钉账号为钉钉管理员账号,从钉钉后台获取appkey和appsecret
def getaccseetoken():
request = dingtalka.api.OapiGettokenRequest("https://oapi.dingtalk.com/gettoken")
request.appkey="appkey"
request.appsecret="appsecret"
f = request.getResponse()
access_token = f['access_token']
print(access_token)
return access_token
获取部门节点下userID
由于一次性只能读取到50条记录,所以要进行切片处理
def get_userid_pro(access_token):
user_dept=[] #获部门下所有的部门节点
userid_name=[] #获取部门下所有人员id信息
userid_id=[]
request= dingtalka.api.OapiV2DepartmentListsubidRequest("https://oapi.dingtalk.com/topapi/v2/department/listsubid")
request.dept_id='XXXXX' #获取优先级最大的部门节点
dept_idmain = request.getResponse(access_token) #获取到部门节点下所有部门节点
userid = list(dept_idmain['result']['dept_id_list'])
user_dept.extend(userid)
for dept in userid:
request.dept_id = dept
dept_idmain = request.getResponse(access_token)
userid = list(dept_idmain['result']['dept_id_list'])
user_dept.extend(userid) # 获取部门下所有的部门节点,后续根据该节点读取部门人员id信息
while len(userid)!=0:
for j in userid:
request.dept_id = j
dept_idmain1 = request.getResponse(access_token)
userid1 = list(dept_idmain1['result']['dept_id_list'])
user_dept.extend(userid1)
userid=userid1
req = dingtalka.api.OapiV2UserListRequest("https://oapi.dingtalk.com/topapi/v2/user/list")
req.cursor = 0
req.size = 30
req.order_field = "entry_asc"
req.contain_access_limit =False
req.language = "zh_CN"
for i in user_dept:
req.dept_id = i
g = req.getResponse(access_token)
for j in g['result']['list']:
value=(j["userid"],j["dept_id_list"][0],j["name"])
value1=j["userid"]
userid_name.append(value)
userid_id.append(value1)
return userid_name,userid_id
获取打卡记录
def get_attendence_listrecord(userid, access_token, day):
# 获取打卡详情
request = dingtalka.api.OapiAttendanceListRecordRequest('https://oapi.dingtalk.com/attendance/list')
request.workDateFrom = str(dt.datetime.now() - day * dt.timedelta(days=1))
request.workDateTo = str(dt.datetime.now())
request.userIdList = userid
request.offset = 0
request.limit = 50
f = request.getResponse(access_token)
h = []
h.append(f)
while ('hasMore',True) in f.items(): #判断是否有更多数值
request.offset = request.offset+request.limit
f = request.getResponse(access_token)
h.append(f)
return h
def get_value(userid_in, access,days):
l = []
users = []
if len(userid_in)>50:
start = 0
end = 49
while end<len(userid_in):
users.append(userid_in[start:end])
start +=49
end = start+50
users.append(userid_in[start:end])
else:
users.append(userid_in[0:len(userid_in)])
for userid_in_in in users:
reponse = get_attendence_listrecord(userid_in_in, access, day=days)
for i in range(len(reponse)):
for respose in reponse[i]['recordresult']:
if respose['sourceType'] != 'SYSTEM':
value = (
respose['userId'], respose['checkType'], str(dt.datetime.fromtimestamp(int(respose['userCheckTime']) / 1000)),respose['locationResult'])
l.append(value)
return l
将读取的考勤数据存入数据库中
db = pymysql.connect(
host='IP位置',
port=端口号,
user='账号',
password='密码',
db='数据库名称',
charset="utf8")
cursor = db.cursor()
def insert_username(access_token):
query = """insert ignore into api_test_user (userid, dept_id,name
) values (%s,%s,%s)"""
value = get_userid_pro(access_token)
for record in value:
cursor.execute(query, record)
db.commit()
def insert(userid, access_token,days):
query = """insert ignore into api_test (userid, duty,time,type
) values (%s,%s,%s,%s)"""
value = get_value(userid, access_token,days)
for record in value:
cursor.execute(query, record)
db.commit()
结束