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()

结束