日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python学习之钉钉打卡

發布時間:2023/12/14 python 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python学习之钉钉打卡 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

python學習之釘釘打卡

  • 背景
  • 原理
  • 實現
    • 一、準備
    • 二、代碼

背景

曾經寫過幾個python小工具,刷快手、自動答題、刷火車票、爬電影天堂電影…,最近因為釘釘成了我們公司官方軟件,所以,你懂得啦,呵呵。剛好手頭有個退休的小米4安卓機,讓python來釘釘打卡,這需要借助adb,因為只有adb才能讓我們的電腦跟安卓手機交互。該文章內容僅僅只是為了學習,最好不要用于實際打卡(要打我也攔不住)。

原理

  • python命令行庫顯示調用adb,利用adb命令做點擊、截屏、滑動操作。
  • adb獲取當前屏幕布局xml,解析xml,找到需要點擊或者滑動的元素,實現安卓手機的控制。
  • adb打卡操作成功后,做一個python郵件或者短信通知提醒打卡結果。
  • 實現

    一、準備

  • 首先要下載一個adb工具,這里我直接下載好了一個工具。
  • VSCode最新版、python3.7
  • 二、代碼

  • python需要調用adb工具,首先寫一個通用的cmd命令行工具類。
  • import shlex import datetime import subprocess import timedef executeCommand(cmd,cwd=None,timeout=None,shell=False):if shell:cmdStringList = cmdelse:cmdStringList = shlex.split(cmd)if timeout:endTime = datetime.datetime.now() + datetime.timedelta(seconds=timeout)sub = subprocess.Popen(cmdStringList,cwd=cwd,stdin=subprocess.PIPE,stdout=subprocess.PIPE,shell=shell,bufsize=4096)while sub.poll() is None:time.sleep(0.1)if timeout:if endTime <= datetime.datetime.now():raise Exception('Timeout: {}'.format(cmd))return sub.stdout.read()if __name__ == "__main__":print(executeCommand("ls"))
  • 獲取安卓設備編號
  • currentPath = os.getcwd() print('當前路徑:{}'.format(currentPath)) # 殺死存在的adb.exe進程 print('start------預殺死存在的adb.exe------start') cuscmd.executeCommand('taskkill /im adb.exe /f',currentPath) print('end------預殺死存在的adb.exe------end') # 連接設備,獲取設備編號 out=cuscmd.executeCommand('adb/adb devices',currentPath) deviceListStr=out.decode(encoding="utf-8") print('設備編號:{}'.format(deviceListStr))
  • 執行點擊
  • # 查找符合要求的字符串(第4行開始讀) deviceListStr = deviceListStr.split('\r\n',3)[3] deviceList=re.findall(r'[A-Za-z0-9/.:]+',deviceListStr) total = len(deviceList) if len(deviceList) > 1:dtotal = Decimal(total)deviceNum = (Decimal(dtotal))/Decimal(2)print('發現'+str(deviceNum)+'臺手機設備')# 設備id列表deviceId = []for i in range(0,int(deviceNum)):deviceId.append(deviceList[2*i])print(deviceId)# 獲取每個設備的應用包名for id in deviceId:# 啟動應用# 檢查屏幕是否熄滅,熄滅是不能獲取到正確的xml頁面布局cmdStr = 'adb/adb -s '+id+' shell dumpsys window policy|grep "mScreenOnEarly"'out=cuscmd.executeCommand(cmdStr,currentPath)returnStr=out.decode(encoding="utf-8").strip()print('獲取屏幕信息:{}'.format(returnStr))if 'mScreenOnEarly=false' in returnStr:# 點亮屏幕print('當前設備屏幕熄滅,點亮屏幕')cuscmd.executeCommand('adb/adb -s '+id+' shell input keyevent 26',currentPath)# 關閉應用out=cuscmd.executeCommand('adb/adb -s '+id+' shell am force-stop com.alibaba.android.rimet',currentPath)stopStr=out.decode(encoding="utf-8").strip()print('關閉信息:{}'.format(stopStr))out=cuscmd.executeCommand('adb/adb -s '+id+' shell am start -n com.alibaba.android.rimet/com.alibaba.android.rimet.biz.LaunchHomeActivity',currentPath)startStr=out.decode(encoding="utf-8").strip()print('啟動信息:{}'.format(startStr))# 延時15秒給應用足夠的時間完成釘釘啟動time.sleep(15)# 創建臨時目錄listdir=os.listdir(currentPath)tempPath = os.path.join(currentPath,'temp')if 'temp' not in listdir:print('文件夾temp不存在,創建temp')os.mkdir(tempPath)# 路徑\\轉/tempPath = tempPath.replace('\\','/')# 獲取設備名稱out=cuscmd.executeCommand('adb/adb -s '+id+' shell getprop ro.product.model',currentPath)modelStr=out.decode(encoding="utf-8").strip().replace(r' ','_')print('獲取設備名稱:{}'.format(modelStr))# 獲取釘釘應用版本號out=cuscmd.executeCommand('adb/adb -s '+id+' shell pm dump com.alibaba.android.rimet | grep "versionName"',currentPath)returnStr=out.decode(encoding="utf-8").strip()ddVersion = re.findall(r'[0-9/.:]+',returnStr)[0]print('獲取釘釘版本號:{}'.format(ddVersion))listdir=os.listdir(tempPath)# 依次點擊按鈕打卡DDClick(id,modelStr,ddVersion,currentPath,tempPath,listdir).clickWork().clickKQDK().clickSXBDK().showResult()# 發送短信# tencentsms.sendmessage('18672332926',['釘釘打卡','已經成功打開啦',time.strftime("%Y年%m月%d日%H:%M:%S", time.localtime())])# 關閉應用out=cuscmd.executeCommand('adb/adb -s '+id+' shell am force-stop com.alibaba.android.rimet',currentPath)stopStr=out.decode(encoding="utf-8").strip()print('關閉信息:{}'.format(stopStr)) else :print('未發現任何手機設備') print('結束')
  • 具體點擊操作的類 ddclick
  • import cuscmd from decimal import Decimal import time import re import os import utils import json import datetime import qqemail class DDClick:def __init__(self,id,modelStr,ddVersion,currentPath,tempPath,listdir):self.mainXMLName = modelStr+'_'+ddVersion+'_mainui.xml'self.workXMLName = modelStr+'_'+ddVersion+'_workui.xml'self.sxbdkXMLName = modelStr+'_'+ddVersion+'_sxbdkui.xml'self.listdir = listdirself.tempPath = tempPathself.currentPath = currentPathself.id = id# 顯示打卡結果def showResult(self):xmlName = self.sxbdkXMLNametempPath = self.tempPathcurrentPath = self.currentPathid = self.idself.__createXML(id,xmlName,self.listdir,currentPath,tempPath,force=True)# 獲取打卡頁面的打卡完成# 讀文件with open(os.path.join(tempPath,xmlName), 'r',encoding='utf-8') as f:xmlContentStr = json.dumps(utils.xmlToJsonDict(f.read())).encode('utf-8').decode('unicode_escape')f.close()index = 0# 查詢關鍵字index = xmlContentStr.find("打卡時間")totalIndex = len(xmlContentStr)-1# 截屏self.__screencapDK(id,currentPath,tempPath)# 圖片轉base64base64Str = utils.imgToBase64(os.path.join(tempPath,'dkscreen.png'))# 讀html模板emailtemplate = ''with open('emailtemplate.txt', 'r',encoding='utf-8') as hf:emailtemplate = hf.read()hf.close()while index > -1:# 反向查找@content-descsIndex = xmlContentStr.rfind('@content-desc',0,index-17)# 正向查找@content-desceIndex = xmlContentStr.find('@content-desc',index,totalIndex)printValue = '打卡時間'printValue1 = '打開地址'if sIndex>-1 and eIndex>-1:sbTimeStr = xmlContentStr[sIndex+17:sIndex+26]dkTimeStr = xmlContentStr[eIndex+17:eIndex+22]# 查找打卡地址sNodeIndex = xmlContentStr.find('node"',eIndex,totalIndex)dkAddressStr = ''sDKAddressIndex = 0searchIndex = sNodeIndex+6while len(dkAddressStr) == 0 and sDKAddressIndex >= 0:sDKAddressIndex = xmlContentStr.find('@content-desc',searchIndex,totalIndex)eDKAddressIndex = xmlContentStr.find('",',sDKAddressIndex+13,totalIndex)dkAddressStr = xmlContentStr[sDKAddressIndex+17:eDKAddressIndex]searchIndex = eDKAddressIndex+6printValue=sbTimeStr+' '+printValue+''+dkTimeStrprintValue1 = printValue1+' '+dkAddressStrprintStr = '''-------------------------打卡結果-------------------------{}{}---------------------------------------------------------'''.format(printValue,printValue1)print(printStr)emailStr = emailtemplate.format(sbTimeStr,dkTimeStr,dkAddressStr,base64Str)# 發送郵件通知qqemail.sendhtml(emailStr)index = xmlContentStr.find("打卡時間",index+4)# 自動判定上下班打卡def clickSXBDK(self):currentDateTime = datetime.datetime.now()print('>>>當前系統時間:{}'.format(datetime.datetime.strftime(currentDateTime, "%Y-%m-%d %H:%M")))currentDateStr = datetime.datetime.strftime(currentDateTime,'%Y-%m-%d')xmlName = self.sxbdkXMLNametempPath = self.tempPathcurrentPath = self.currentPathid = self.idself.__createXML(id,xmlName,self.listdir,currentPath,tempPath,force=True)try:# 獲取上下班時間sbTimeStr = currentDateStr+' '+self.__getSXBTime(xmlName,'上班時間')print('>>>今天上班時間:{}<<<'.format(sbTimeStr))xbTimeStr = currentDateStr+' '+self.__getSXBTime(xmlName,'下班時間')print('>>>今天下班時間:{}<<<'.format(xbTimeStr))sbTime = datetime.datetime.strptime(sbTimeStr, "%Y-%m-%d %H:%M")xbTime = datetime.datetime.strptime(xbTimeStr, "%Y-%m-%d %H:%M")if currentDateTime < sbTime:print('>>>上班打卡<<<')# 點擊對應的圖標self.__click(xmlName,0,0,'上班打卡',self.__clickByPoint)if currentDateTime > xbTime:print('>>>下班打卡<<<')# 點擊對應的圖標self.__click(xmlName,0,0,'下班打卡',self.__clickByPoint)else:print('>>>不在打卡范圍,正確范圍是:{}前,或{}后<<<'.format(sbTimeStr,xbTimeStr))except Exception as e:print(e)self.clickSXBDK()return self# 點擊考勤打卡圖標def clickKQDK(self):workXMLName = self.workXMLNametempPath = self.tempPathcurrentPath = self.currentPathid = self.idself.__createXML(id,workXMLName,self.listdir,currentPath,tempPath)# 點擊對應的圖標self.__click(workXMLName,0,-22,'考勤打卡',self.__clickByPoint)return self# 點擊工作def clickWork(self):mainXMLName = self.mainXMLNametempPath = self.tempPathcurrentPath = self.currentPathid = self.idself.__createXML(id,mainXMLName,self.listdir,currentPath,tempPath)# 讀文件with open(os.path.join(tempPath,mainXMLName), 'r',encoding='utf-8') as f:mainuiDict=utils.xmlToJsonDict(f.read())nodes = mainuiDict['hierarchy']['node']['node']['node']['node']['node']['node']['node']for node in nodes:if node['@resource-id'] == 'com.alibaba.android.rimet:id/bottom_tab':nodeItems = node['node']for nodeItem in nodeItems:if 'node' in nodeItem:nodeChildren = nodeItem['node']for nodeChild in nodeChildren:if nodeChild['@resource-id'] == 'com.alibaba.android.rimet:id/home_bottom_tab_button_work':zbStr = nodeChild['@bounds']self.__clickByPoint(zbStr)return self# 創建文件def __createXML(self,id,xmlName,listdir,currentPath,tempPath,force = False):# 檢查頁面是否正確cmd = 'adb/adb -s '+id+' shell "dumpsys window | grep mCurrentFocus"'out=cuscmd.executeCommand(cmd,currentPath)returnStr=out.decode(encoding="utf-8").strip()print('獲取頁面所在activity信息:{}'.format(returnStr))if 'com.alibaba.android.rimet' not in returnStr:# 點擊電源鍵cuscmd.executeCommand('adb/adb -s '+id+' shell input keyevent 26',currentPath)# 檢查屏幕是否熄滅,熄滅是不能獲取到正確的xml頁面布局cmd = 'adb/adb -s '+id+' shell dumpsys window policy|grep "mScreenOnEarly"'out=cuscmd.executeCommand(cmd,currentPath)returnStr=out.decode(encoding="utf-8").strip()print('獲取屏幕信息:{}'.format(returnStr))if 'mScreenOnEarly=false' in returnStr:# 點亮屏幕print('當前設備屏幕熄滅,點亮屏幕')cuscmd.executeCommand('adb/adb -s '+id+' shell input keyevent 26',currentPath)if xmlName not in listdir or force is True:print(xmlName+'不存在或強制更新'+xmlName+',創建新的'+xmlName)# 獲取xml頁面布局cmd = 'adb/adb -s '+id+' shell uiautomator dump /data/local/tmp/'+xmlName# print('獲取xml頁面布局命令:{}'.format(cmd))out=cuscmd.executeCommand(cmd,currentPath)returnStr=out.decode(encoding="utf-8").strip()print('獲取頁面UIXML信息:{}'.format(returnStr))# 將xml放置本地cmd = 'adb/adb -s '+id+' pull /data/local/tmp/'+xmlName+' '+tempPath# print('將xml放置本地命令:{}'.format(cmd))out=cuscmd.executeCommand(cmd,currentPath)returnStr=out.decode(encoding="utf-8").strip()print('保存頁面UIXML信息:{}'.format(returnStr))# 截釘釘打卡屏def __screencapDK(self,id,currentPath,tempPath,imgName='dkscreen.png'):cmd = 'adb/adb -s '+id+' shell screencap -p /data/local/tmp/'+imgNameout=cuscmd.executeCommand(cmd,currentPath)returnStr=out.decode(encoding="utf-8").strip()print('獲取釘釘打卡截屏:{}'.format(returnStr))cmd = 'adb/adb -s '+id+' pull /data/local/tmp/'+imgName+' '+tempPathout=cuscmd.executeCommand(cmd,currentPath)returnStr=out.decode(encoding="utf-8").strip()print('保存釘釘打卡截屏:{}'.format(returnStr))# 點擊坐標def __clickByPoint(self,zbStr,xoffset=0,yoffset=0):print('當前點擊坐標范圍為:{}'.format(zbStr))# 轉化為坐標zbList = re.findall(r'[0-9]+',zbStr)lx = Decimal(zbList[0])ly = Decimal(zbList[1])rx = Decimal(zbList[2])ry = Decimal(zbList[3])# 計算中心點坐標mx = lx+(rx-lx)/2+xoffsetmy = ly+(ry-ly)/2+yoffsetprint('當前點擊坐標為:{}'.format('['+str(round(mx,0))+','+str(round(my,0))+']'))# 點擊mPointStr = str(round(mx,0))+' '+str(round(my,0))out=cuscmd.executeCommand('adb/adb -s '+self.id+' shell input tap '+mPointStr,self.currentPath)clickStr=out.decode(encoding="utf-8").strip()print('點擊信息:{}'.format(clickStr))# 延時6秒給應用足夠的時間渲染頁面time.sleep(6)# 點擊操作def __click(self,xmlName,xoffset=0,yoffset=0,keywords='',callback=None):tempPath = self.tempPath# 讀文件with open(os.path.join(tempPath,xmlName), 'r',encoding='utf-8') as f:workuiStr = json.dumps(utils.xmlToJsonDict(f.read())).encode('utf-8').decode('unicode_escape')# 查詢關鍵字index = workuiStr.find(keywords)if index > -1:# 反向查找{sIndex = workuiStr.rfind('{',0,index)# 正向查找}eIndex = workuiStr.find('}',index,len(workuiStr)-1)if sIndex>-1 and eIndex>-1:kqdkStr = workuiStr[sIndex:eIndex+1]kqdkDict = json.loads(kqdkStr)zbStr = kqdkDict['@bounds']if callback != None:callback(zbStr,xoffset,yoffset)# 獲取上下班時間def __getSXBTime(self,xmlName,keyWords):tempPath = self.tempPathtimeStr = None# 讀文件with open(os.path.join(tempPath,xmlName), 'r',encoding='utf-8') as f:xmlContentStr = f.read()# 查詢關鍵字index = xmlContentStr.find(keyWords)if index > -1:# 查找到時間并截取出來timeStr = xmlContentStr[index+4:index+9]print('得到的時間為:{}'.format(timeStr))return timeStr
  • 郵件通知
  • import smtplib from email.mime.text import MIMEText from email.header import Header # 發送服務器 host='smtp.qq.com' # 發送郵箱 user='xxxxx@qq.com' # 授權碼 pwd='' # 接收郵箱(改為自己需要接收的郵箱) receive=['xxxxx@qq.com']def send(msg):try:smtp = smtplib.SMTP()smtp.connect(host, 25)smtp.login(user, pwd)smtp.sendmail(user, receive, msg.as_string())smtp.quit()print(">>>郵件發送成功!<<<")except smtplib.SMTPException as e:print(">>>郵件發送失敗<<<", e)def sendhtml(content):msg = MIMEText(content, 'html', 'utf-8')#from表示發件人顯示內容msg['From'] = Header("釘釘自動打卡助手", 'utf-8')#to表示收件人顯示內容msg['To'] = Header('釘釘用戶', 'utf-8')# subject,郵件標頭subject = '釘釘自動打卡郵件通知'msg['subject'] = Header(subject, 'utf-8')send(msg)
  • email模板
  • <meta charset="utf-8"><div class="content-wrap" style="margin: 0px auto; overflow: hidden; padding: 0px; border: 0px solid rgb(238, 238, 238); width: 600px;"><!----><div class="full" tindex="1" style="margin: 0px auto; max-width: 600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width: 600px;"><tbody><tr><td style="direction: ltr; width: 600px; font-size: 0px; padding-bottom: 0px; text-align: center; vertical-align: top; background-image: url(&quot;&quot;); background-repeat: no-repeat; background-size: 100px; background-position: 10% 50%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" width="100%" style="vertical-align: top;"><tr><td align="left" style="font-size: 0px; padding: 20px;"><div class="text" style="font-family: &quot;Microsoft YaHei&quot;; overflow-wrap: break-word; margin: 0px; text-align: center; line-height: 24px; color: rgb(250, 137, 123); font-size: 24px;"><div><p style="text-size-adjust: none; word-break: break-word; line-height: 24px; font-size: 24px; margin: 0px;"><strong>打卡時間</strong></p></div></div></td></tr></table></td></tr></tbody></table></div><div tindex="2" style="margin: 0px auto; max-width: 600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" style="background-color: rgb(134, 227, 206); background-image: url(&quot;&quot;); background-repeat: no-repeat; background-size: 100px; background-position: 1% 50%;"><tbody><tr><td style="direction: ltr; font-size: 0px; text-align: center; vertical-align: top; width: 600px;"><table width="100%" border="0" cellpadding="0" cellspacing="0" style="vertical-align: top;"><tbody><tr><td style="width: 33.3333%; max-width: 33.3333%; min-height: 1px; font-size: 13px; text-align: left; direction: ltr; vertical-align: top; padding: 0px;"><div class="full" style="margin: 0px auto; max-width: 600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width: 200px;"><tbody><tr><td style="direction: ltr; font-size: 0px; padding-top: 0px; text-align: center; vertical-align: top;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" width="100%" style="vertical-align: top;"><tr><td align="center" vertical-align="middle" style="padding-top: 40px; width: 200px; background-image: url(&quot;&quot;); background-size: 100px; background-position: 10% 50%; background-repeat: no-repeat;"></td></tr></table></td></tr></tbody></table></div></td><td style="width: 33.3333%; max-width: 33.3333%; min-height: 1px; font-size: 13px; text-align: left; direction: ltr; vertical-align: top; padding: 0px;"><div class="full" style="margin: 0px auto; max-width: 600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width: 200px;"><tbody><tr><td style="direction: ltr; width: 200px; font-size: 0px; padding-bottom: 0px; text-align: center; vertical-align: top; background-image: url(&quot;&quot;); background-repeat: no-repeat; background-size: 100px; background-position: 10% 50%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" width="100%" style="vertical-align: top;"><tr><td align="left" style="font-size: 0px; padding: 26px 20px;"><div class="text" style="font-family: &quot;Microsoft YaHei&quot;; overflow-wrap: break-word; margin: 0px; text-align: center; line-height: 12px; color: rgb(32, 32, 32); font-size: 16px;"><div><p style="text-size-adjust: none; word-break: break-word; line-height: 12px; font-size: 16px; margin: 0px;"><strong>{0}</strong></p></div></div></td></tr></table></td></tr></tbody></table></div></td><td style="width: 33.3333%; max-width: 33.3333%; min-height: 1px; font-size: 13px; text-align: left; direction: ltr; vertical-align: top; padding: 0px;"><div class="full" style="margin: 0px auto; max-width: 600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width: 200px;"><tbody><tr><td style="direction: ltr; font-size: 0px; padding-top: 0px; text-align: center; vertical-align: top;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" width="100%" style="vertical-align: top;"><tr><td align="center" vertical-align="middle" style="padding-top: 40px; width: 200px; background-image: url(&quot;&quot;); background-size: 100px; background-position: 10% 50%; background-repeat: no-repeat;"></td></tr></table></td></tr></tbody></table></div></td></tr></tbody></table></td></tr></tbody></table></div><div tindex="3" style="margin: 0px auto; max-width: 600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" style="background-image: url(&quot;&quot;); background-repeat: no-repeat; background-size: 100px; background-position: 1% 50%;"><tbody><tr><td style="direction: ltr; font-size: 0px; text-align: center; vertical-align: top; width: 600px;"><table width="100%" border="0" cellpadding="0" cellspacing="0" style="vertical-align: top;"><tbody><tr><td style="width: 25%; max-width: 25%; min-height: 1px; font-size: 13px; text-align: left; direction: ltr; vertical-align: top; padding: 0px;"><div class="full" style="margin: 0px auto; max-width: 600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width: 150px;"><tbody><tr><td style="direction: ltr; font-size: 0px; padding-top: 0px; text-align: center; vertical-align: top;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" width="100%" style="vertical-align: top;"><tr><td align="center" vertical-align="middle" style="padding-top: 120px; background-color: rgb(255, 221, 148); width: 150px; background-image: url(&quot;&quot;); background-size: 100px; background-position: 10% 50%; background-repeat: no-repeat;"></td></tr></table></td></tr></tbody></table></div></td><td style="width: 25%; max-width: 25%; min-height: 1px; font-size: 13px; text-align: left; direction: ltr; vertical-align: top; padding: 0px;"><div columnnumber="3"><table align="center" border="0" cellpadding="0" cellspacing="0" style="width: 100%;"><tbody><tr><td style="direction: ltr; font-size: 0px; text-align: center; vertical-align: top; border: 0px;"><a target="_blank" href="javascript:;" style="cursor: default;"><div class="mj-column-per-50" style="width: 100%; max-width: 100%; font-size: 13px; text-align: left; direction: ltr; display: inline-block; vertical-align: top;"><table border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse; border-spacing: 0px; width: 100%; vertical-align: top;"><tr><td align="center" border="0" style="font-size: 0px; word-break: break-word;"><div class="full" style="margin: 0px auto; max-width: 600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width: 150px;"><tbody><tr><td style="direction: ltr; width: 150px; font-size: 0px; padding-bottom: 0px; text-align: center; vertical-align: top; background-color: rgb(221, 230, 165); background-image: url(&quot;&quot;); background-repeat: no-repeat; background-size: 100px; background-position: 10% 50%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" width="100%" style="vertical-align: top;"><tr><td align="left" style="font-size: 0px; padding: 20px;"><div class="text" style="font-family: &quot;Microsoft YaHei&quot;; overflow-wrap: break-word; margin: 0px; text-align: right; line-height: 20px; color: rgb(32, 32, 32); font-size: 16px;"><div><p style="text-size-adjust: none; word-break: break-word; line-height: 20px; font-size: 16px; margin: 0px;"><strong>打卡時間</strong></p></div></div></td></tr></table></td></tr></tbody></table></div></td></tr></table></div><div class="mj-column-per-50" style="width: 100%; max-width: 100%; font-size: 13px; text-align: left; direction: ltr; display: inline-block; vertical-align: top;"><table border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse; border-spacing: 0px; width: 100%; vertical-align: top;"><tr><td align="center" border="0" style="font-size: 0px; word-break: break-word;"><div class="full" style="margin: 0px auto; max-width: 600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width: 150px;"><tbody><tr><td style="direction: ltr; width: 150px; font-size: 0px; padding-bottom: 0px; text-align: center; vertical-align: top; background-color: rgb(221, 230, 165); background-image: url(&quot;&quot;); background-repeat: no-repeat; background-size: 100px; background-position: 10% 50%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" width="100%" style="vertical-align: top;"><tr><td align="left" style="font-size: 0px; padding: 20px;"><div class="text" style="font-family: &quot;Microsoft YaHei&quot;; overflow-wrap: break-word; margin: 0px; text-align: right; line-height: 20px; color: rgb(32, 32, 32); font-size: 16px;"><div><p style="text-size-adjust: none; word-break: break-word; line-height: 20px; font-size: 16px; margin: 0px;"><strong>打卡地址</strong></p></div></div></td></tr></table></td></tr></tbody></table></div></td></tr></table></div></a></td></tr></tbody></table></div></td><td style="width: 50%; max-width: 50%; min-height: 1px; font-size: 13px; text-align: left; direction: ltr; vertical-align: top; padding: 0px;"><div columnnumber="3"><table align="center" border="0" cellpadding="0" cellspacing="0" style="width: 100%;"><tbody><tr><td style="direction: ltr; font-size: 0px; text-align: center; vertical-align: top; border: 0px;"><a target="_blank" href="javascript:;" style="cursor: default;"><div class="mj-column-per-50" style="width: 100%; max-width: 100%; font-size: 13px; text-align: left; direction: ltr; display: inline-block; vertical-align: top;"><table border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse; border-spacing: 0px; width: 100%; vertical-align: top;"><tr><td align="center" border="0" style="font-size: 0px; word-break: break-word;"><div class="full" style="margin: 0px auto; max-width: 600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width: 300px;"><tbody><tr><td style="direction: ltr; width: 300px; font-size: 0px; padding-bottom: 0px; text-align: center; vertical-align: top; background-color: rgb(255, 221, 148); background-image: url(&quot;&quot;); background-repeat: no-repeat; background-size: 100px; background-position: 10% 50%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" width="100%" style="vertical-align: top;"><tr><td align="left" style="font-size: 0px; padding: 20px;"><div class="text" style="font-family: &quot;Microsoft YaHei&quot;; overflow-wrap: break-word; margin: 0px; text-align: left; line-height: 20px; color: rgb(32, 32, 32); font-size: 16px;"><div><p style="text-size-adjust: none; word-break: break-word; line-height: 20px; font-size: 16px; margin: 0px;"><strong>{1}</strong></p></div></div></td></tr></table></td></tr></tbody></table></div></td></tr></table></div><div class="mj-column-per-50" style="width: 100%; max-width: 100%; font-size: 13px; text-align: left; direction: ltr; display: inline-block; vertical-align: top;"><table border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse; border-spacing: 0px; width: 100%; vertical-align: top;"><tr><td align="center" border="0" style="font-size: 0px; word-break: break-word;"><div class="full" style="margin: 0px auto; max-width: 600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width: 300px;"><tbody><tr><td style="direction: ltr; width: 300px; font-size: 0px; padding-bottom: 0px; text-align: center; vertical-align: top; background-color: rgb(255, 221, 148); background-image: url(&quot;&quot;); background-repeat: no-repeat; background-size: 100px; background-position: 10% 50%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" width="100%" style="vertical-align: top;"><tr><td align="left" style="font-size: 0px; padding: 20px;"><div class="text" style="font-family: &quot;Microsoft YaHei&quot;; overflow-wrap: break-word; margin: 0px; text-align: left; line-height: 20px; color: rgb(32, 32, 32); font-size: 16px;"><div><p style="text-size-adjust: none; word-break: break-word; line-height: 20px; font-size: 16px; margin: 0px;"><strong>{2}</strong></p></div></div></td></tr></table></td></tr></tbody></table></div></td></tr></table></div></a></td></tr></tbody></table></div></td></tr></tbody></table></td></tr></tbody></table></div><div tindex="4" style="margin: 0px auto; max-width: 600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" style="background-color: rgb(255, 255, 255); background-image: url(&quot;&quot;); background-repeat: no-repeat; background-size: 100px; background-position: 1% 50%;"><tbody><tr><td style="direction: ltr; font-size: 0px; text-align: center; vertical-align: top; width: 600px;"><table width="100%" border="0" cellpadding="0" cellspacing="0" style="vertical-align: top;"><tbody><tr><td style="width: 100%; max-width: 100%; min-height: 1px; font-size: 13px; text-align: left; direction: ltr; vertical-align: top; padding: 0px;"><div class="full" style="margin: 0px auto; max-width: 600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width: 600px;"><tbody><tr><td style="direction: ltr; width: 600px; font-size: 0px; padding-bottom: 0px; text-align: center; vertical-align: top;"><div style="display: inline-block; vertical-align: top; width: 100%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" width="100%" style="vertical-align: top;"><tr><td style="font-size: 0px; word-break: break-word; background-color: rgb(204, 171, 216); width: 580px; text-align: center; padding: 10px;"><div><img height="auto" alt="釘釘打卡圖片" width="580" src="{3}" style="box-sizing: border-box; border: 0px; display: inline-block; outline: none; text-decoration: none; height: auto; max-width: 100%; padding: 0px;"></div></td></tr></table></div></td></tr></tbody></table></div></td></tr></tbody></table></td></tr></tbody></table></div></div>
  • 釘釘打卡成功后通知截圖

  • 8. 完整代碼請訪問我的碼云鏈接。

    總結

    以上是生活随笔為你收集整理的python学习之钉钉打卡的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。