前言:公司内部oa和取数系统很渣,为了安全性不支持mysql链接,也不支持chrome,所以selenium不能用,必须每天手动取数。之前接触了PyMouse和PyKeyboard,想试下是否可以完成自动化取数。初步实现了,但是还存在很多问题,主要如下:
1、对于网络速度有要求,如果在等待时间内下一个网页无法弹出来(或者某个取数时间比较长不出来),就会导致后续步骤全部出错;
2、不同电脑的显示模式不同,有可能坐标轴都需要变动;
# coding=utf-8
from pymouse import PyMouse
from pykeyboard import PyKeyboard
import os
import time
from datetime import datetime
import win32clipboard
import win32con
import getpass
import traceback
def click_and_sleep(h, v, seconds):
'''点击并暂停'''
m.click(h, v)
time.sleep(seconds)
def alt_table():
'''alt_table切换页面'''
k.press_key(k.alt_key)
time.sleep(1)
k.tap_key(k.tab_key)
time.sleep(1)
k.release_key(k.alt_key)
def get_this_month():
'''获得月份'''
this_day = datetime.now().strftime("%d")
month = int(datetime.now().strftime("%m"))
if this_day == "01": return str(month - 1) + '月'
else: return str(month) + '月'
def copy_and_paste(value):
'''把值复制黏贴'''
win32clipboard.OpenClipboard()
win32clipboard.EmptyClipboard()
win32clipboard.SetClipboardText(value, win32clipboard.CF_UNICODETEXT)
win32clipboard.CloseClipboard()
time.sleep(1)
k.press_keys([k.control_key, 'v']) # 黏贴
def get_drag_value(start_coordinate, end_coordinate):
'''获取鼠标圈中的内容'''
m.move(start_coordinate[0], start_coordinate[1])
m.drag(end_coordinate[0], end_coordinate[1])
time.sleep(1)
k.press_keys([k.control_key, 'c']) # 复制
win32clipboard.OpenClipboard()
value = win32clipboard.GetClipboardData(win32con.CF_UNICODETEXT)
win32clipboard.CloseClipboard()
return value
def download(key, value):
'''下载文件'''
search(key)
try:
answer = get_drag_value((1131, 376), (895, 376))
except:
answer = key
finally:
if answer == key: #判断取数目的和key是否一致
click_and_sleep(1556, 369, 5) # 点击“下载”
click_and_sleep(1022, 545, 1) # 点击“保存”
# 注:这里产生的下载框可能会和系统有关(和是否装了迅雷等也有关),我这里使用的是win7默认自带的下载器,且把窗口拉大到全屏
if 'CDMA' in key: # 第一次有可能下载的地址不对,需要切换,第二次开始就正常了
m.click(1127, 44) # 选择地址栏
k.tap_key(k.backspace_key) # 删除之前的地址
copy_and_paste(path_data) # 输入数据文件夹的路径
click_and_sleep(1690, 42, 1) # 切换路径
m.click(1614, 929) # 点击“文件名”栏
copy_and_paste(value)
time.sleep(1)
click_and_sleep(1756, 1000, 1) # 点击“保存”
click_and_sleep(1022, 537, 3) # 点击“替换”——>“是”
click_and_sleep(1120, 586, 1) # 点击“关闭”
else:
k.tap_key(k.function_keys[5]) # 按F5刷新
login_idap()
download(key ,value)
def get_FileModifyTime(filePath):
'''获取文件修改时间,以"12-26"形式展示'''
t = os.path.getmtime(filePath)
timeStruct = time.localtime(t)
return time.strftime('%m-%d', timeStruct)
def get_FileSize(filePath):
'''获取文件大小,单位是根据文件大小变化;
获得的结果是一个元组,第一个元素是不带单位的数字(内在单位是B),第二个是带单位的数字(比如1.20KB)'''
fsize1 = os.path.getsize(filePath)
if fsize1 >= 1024*1024: fsize2 = str(float('%.2f' % (fsize1/(1024 * 1024)))) + 'MB'
elif fsize1 >= 1024: fsize2 = str(float('%.2f' % (fsize1/1024))) + 'KB'
else: fsize2 = str(fsize1) + '.00' + 'B'
return fsize1, fsize2
def get_OldFileSize():
'''获得文件更新前的大小(单位B)'''
old_file_size = {}
for value in list_dict.values():
filepath = path_data + value
old_file_size[value] = get_FileSize(filepath)[0]
return old_file_size
def get_OldFileSize2():
'''获得文件更新前的大小(单位根据大小变动)'''
old_file_size = {}
for value in list_dict.values():
filepath = path_data + value
old_file_size[value] = get_FileSize(filepath)[1]
return old_file_size
def file_check(value):
'''检查文件是否下载更新了,更新了返回1,日期更新但大小没变返回2,日期更新但大小变小了返回3,日期没更新返回4'''
this_time = datetime.now().strftime("%m-%d")
filepath = path_data + value
if get_FileModifyTime(filepath) == this_time:
if get_FileSize(filepath)[0] > old_file_size[value]:
print('>>>{}已经更新了!'.format(value))
return 1
elif get_FileSize(filepath)[0] == old_file_size[value]:
print('>>>{}日期更新了,但是大小没变,请注意!'.format(value))
return 2
else:
print('>>>{}日期更新但大小变小了,请注意!'.format(value))
return 3
else:
print('>>>{}日期不对,请注意!'.format(value))
return 4
def redownload(key, value, sleep):
'''重新下载'''
print('>>>{}秒后准备重新取数!'.format(sleep))
time.sleep(sleep)
download(key, value)
answer = file_check(value)
print(answer)
if (answer == 1) or (answer ==2):
print('>>>貌似正常了!')
return 1
else:
print('>>>我已经尽力了,{}还是有问题'.format(value))
return 2
def search(key):
'''根据key在搜索栏里搜索'''
m.click(1118, 267) # 点击“取数目的”
k.tap_key(k.backspace_key, n=10) # 删除之前的搜索内容
copy_and_paste(key)
time.sleep(3)
click_and_sleep(1877, 229, 3) # 点击“查询”
def access(key):
'''取数复用'''
try:
answer = get_drag_value((1131, 376), (895, 376))
except:
answer = key
finally:
if answer == key:
click_and_sleep(1742, 370, 3) # 点击“取数复用”
for i in range(5):
click_and_sleep(1867, 230, 3) # 点击“下一步”
click_and_sleep(1867, 230, 5) # 点击“立即取数”
else:
k.tap_key(k.function_keys[5]) # 按F5刷新
login_idap()
search(key)
access(key)
def login_oa():
'''第一步:登陆oa'''
name = getpass.getuser() # 获取当前系统的用户名
os.startfile('C:\\Users\\' + name + r'\AppData\Local\360Chrome\Chrome\Application\360chrome.exe')
time.sleep(1)
click_and_sleep(1112, 49, 1) #点击地址栏
k.type_string('www.sh.ctc.com') #输入网址
k.tap_key(k.enter_key) #输入回车
time.sleep(3)
click_and_sleep(920, 259, 1) #点击“动态码认证”
click_and_sleep(984, 380, 1) #点击“用户名栏”
k.tap_key(k.backspace_key, n=10)
time.sleep(1)
k.type_string('zhanglei1') #输入用户名
time.sleep(1)
k.tap_key(k.tab_key) #按table到密码框
# m.click(889, 438) #点击密码框
k.type_string('******') #输入密码
m.click(1098, 495) #点击获取动态码
dynamic_code = input('请输入动态码:')
alt_table() #alt+table切换到浏览器页面
time.sleep(1)
m.click(910, 502) # 点击动态码框
copy_and_paste(dynamic_code) #输入动态码
click_and_sleep(956, 556, 3) #点击“登陆”按钮
def login_idap():
'''第二步:打开idap'''
click_and_sleep(765, 183, 3) #点击“我的工作”
click_and_sleep(637, 875, 3) #点击“IDAP智能取数平台”
click_and_sleep(140, 273, 3) #点击“取数管理”
click_and_sleep(71, 298, 3) #点击“我的取数”
def search_and_access():
'''第三步:搜索并取数'''
for key in list_dict.keys():
search(key)
access(key)
def search_and_download():
'''第四步:搜索并下载'''
for key, value in list_dict.items():
download(key, value)
def download_check():
'''第五步:判断下载的文件是否准确,如果不对的话重新下载(主要是针对单转融这类时间比较长的)'''
for key, value in list_dict.items():
answer = file_check(value)
if (answer == 1) or (answer ==2):
continue
elif answer == 3:
redownload(key, value, 5)
continue
elif answer == 4:
answer = redownload(key, value, 200)
if answer == 1:
continue
elif answer == 2:
redownload(key, value, 200)
continue
if __name__ == "__main__":
m = PyMouse()
k = PyKeyboard() #
# print(m.position())
path_data = os.path.abspath('..') + "\\数据\\"
orgin_dict = {'CDMA': 'cdma.xls', '宽带': 'kd.xls', '199+30': '199+30.xls', '精品智能组网': '精品智能组网.xls', '4K': '4k.xls', '单转融': '单转融.xls'}
list_dict = {}
for key, value in orgin_dict.items():
new_key = key + ' ' + get_this_month()
list_dict[new_key] = value
old_file_size = get_OldFileSize()
print(get_OldFileSize2())
try:
login_oa()
login_idap()
search_and_access()
print('>>>数据复用完毕!')
time.sleep(30) #这个根据最大取数时间来定,比如单转融1000秒都未必能好>_<
search_and_download()
print('>>>数据下载完毕!')
download_check()
except:
traceback.print_exc()
finally:
a = input('>>>取数完毕,按回车键退出!')