rpa_hongtao3_refresh.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. import hug
  2. from bottle import route, run
  3. import pyautogui
  4. import random
  5. import time
  6. import os
  7. import pythoncom
  8. import win32gui, win32con, win32process
  9. import psutil
  10. import urllib.parse
  11. import subprocess
  12. import autoit
  13. import datetime
  14. hug.API(__name__).http.output_format = hug.output_format.json
  15. # exePath = r"C:\Program Files\Microsoft Office\root\Office16\EXCEL.EXE"
  16. exePath = r"C:\Program Files\Microsoft Office\Office16\EXCEL.EXE"
  17. # 红桃3选项卡位置
  18. hongTao3PointX = 497
  19. hongTao3PointY = 47
  20. # 数据刷新按钮
  21. refreshButtonPointX = 247
  22. refreshButtonPointY = 102
  23. # 刷新工作簿按钮
  24. refreshSheetPointX = 274
  25. refreshSheetPointY = 174
  26. # 弹框的登录按钮位置
  27. loginButtonPointX = 518
  28. loginButtonPointY = 437
  29. # 刷新完成按钮
  30. refreshEndPointX = 747
  31. refreshEndPointY = 451
  32. # 用来随机的最大最小x、y坐标
  33. minPointX = 511
  34. maxPointX = 1000
  35. minPointY = 282
  36. maxPointY = 600
  37. # excel在进程中的名称
  38. excelProcessName = "EXCEL.EXE"
  39. # 登录提示框
  40. # hongTao3LoginButtonName = "WindowsForms10.Window.8.app.0.182b0e9_r56_ad2"
  41. hongTao3LoginButtonName = "WindowsForms10.Window.8.app.0.182b0e9_r55_ad2"
  42. # 刷新中的按钮名称
  43. refreshIngButtonName = "WindowsForms10.Window.8.app.0.182b0e9_r57_ad2"
  44. # 刷新完成的按钮名称
  45. refreshEndButtonName = "#32770"
  46. def getProcessName(hwnd):
  47. tid, pid = win32process.GetWindowThreadProcessId(hwnd)
  48. processName = psutil.Process(pid).name()
  49. return processName
  50. def getClassName(hwnd):
  51. className = win32gui.GetClassName(hwnd)
  52. return className
  53. ## 获取窗口标题
  54. def getText(hwnd):
  55. text = win32gui.GetWindowText(hwnd)
  56. return text
  57. # 检验卓创的登录失效按钮
  58. # def checkLoginInvalid():
  59. # # 登录失效的弹框(类名: Button)
  60. # # pointX = 1047
  61. # # pointY = 604
  62. # # hwnd = win32gui.WindowFromPoint((pointX, pointY))
  63. # hwnd = win32gui.GetForegroundWindow()
  64. # # print("检验卓创的登录失效按钮:", hwnd)
  65. # if hwnd != 0:
  66. # print("检验卓创的登录失效按钮:processName:", getProcessName(hwnd), ",类名:", getClassName(hwnd))
  67. # if getProcessName(hwnd) == excelProcessName and getClassName(hwnd) == hongTao3LoginButtonName:
  68. # print("好吧,登录失效了")
  69. # pyautogui.moveTo(loginButtonPointX, loginButtonPointY, 0.5)
  70. # pyautogui.click()
  71. # time.sleep(1)
  72. # return True
  73. # else:
  74. # return False
  75. # else:
  76. # return False
  77. # 检验卓创的登录按钮
  78. def checkHongtaoLoginButton():
  79. # 卓创登录的弹框(类名: WindowsForms10.BUTTON.app.0.182b0e9_r93_ad2)
  80. # hwnd = win32gui.WindowFromPoint((loginButtonPointX, loginButtonPointY))
  81. hwnd = win32gui.GetForegroundWindow()
  82. # print("检验卓创的登录按钮:", hwnd)
  83. if hwnd != 0:
  84. className = getClassName(hwnd)
  85. print("检验卓创的登录按钮:processName:", getProcessName(hwnd), ",类名:", className)
  86. lenClassName = len(className)
  87. # if getProcessName(hwnd) == "EXCEL.EXE" and getClassName(hwnd) == "WindowsForms10.BUTTON.app.0.182b0e9_r93_ad2":
  88. if getProcessName(hwnd) == excelProcessName and className == hongTao3LoginButtonName:
  89. print("开始卓创登录")
  90. pyautogui.moveTo(loginButtonPointX, loginButtonPointY, 0.5)
  91. pyautogui.click()
  92. time.sleep(1)
  93. return True
  94. else:
  95. return False
  96. else:
  97. return False
  98. # 检验卓创的数据刷新组件
  99. def checkRefreshEnd():
  100. # 登录失效的弹框(类名: Button)
  101. # 完成了,点击结束
  102. # 等2秒吧
  103. time.sleep(2)
  104. i = 1
  105. n = 1
  106. # hwnd为0的次数,如果超过5次,那么就终止
  107. hwndN = 0
  108. while i < 2:
  109. # hwnd = win32gui.WindowFromPoint((refreshEndPointX, refreshEndPointY))
  110. hwnd = win32gui.GetForegroundWindow()
  111. # print("检验卓创的数据刷新组件:", hwnd)
  112. print("第", n, "次检测")
  113. n = n + 1
  114. print("hwnd:", hwnd)
  115. if hwnd != 0:
  116. # hwnd为0的次数置空
  117. hwndN = 0
  118. print("检验卓创的数据刷新组件:processName:", getProcessName(hwnd), ",类名:", getClassName(hwnd))
  119. if getProcessName(hwnd) == excelProcessName and getClassName(hwnd) == refreshEndButtonName:
  120. print("ok,刷新完成了")
  121. pyautogui.moveTo(refreshEndPointX, refreshEndPointY, 0.5)
  122. pyautogui.click()
  123. time.sleep(1)
  124. return True
  125. # 不用n=2的原因,是因为那个遮罩层可能没那么快出来,万一真实很快就被刷出来了,那么超时500s后,就超时关闭吧
  126. if n > 500:
  127. print("超时500s,默认执行完成吧")
  128. return True
  129. if getProcessName(hwnd) != excelProcessName:
  130. print("目前活动窗口与实际不符,终止执行")
  131. return False
  132. # 等待1s执行
  133. time.sleep(1)
  134. else:
  135. # hwnd为0的次数,如果超过5次,那么就终止
  136. if hwndN > 5:
  137. return False
  138. hwndN = hwndN + 1
  139. # 等待2s执行
  140. time.sleep(2)
  141. @hug.get('/hongtao/server')
  142. def mysteel_chemical_server():
  143. return 1
  144. @hug.get('/hongtao/refresh')
  145. def mysteel_chemical_refresh(FilePath):
  146. pyautogui.FAILSAFE = False
  147. file_path = FilePath
  148. print(FilePath)
  149. screen_width, screen_height = pyautogui.size()
  150. print("当前时间:{};当前屏幕分辨率:{} x {}".format(datetime.datetime.now(), screen_width, screen_height))
  151. pyautogui.FAILSAFE = False
  152. file_path = file_path.replace('"', '')
  153. # 显示桌面
  154. pyautogui.hotkey('win', 'd')
  155. # return "a"
  156. try:
  157. file_path = urllib.parse.unquote(file_path)
  158. fileFullPath = file_path
  159. # print("full_path start")
  160. fileFullPath = fileFullPath.replace("\\\\", "\\")
  161. print("文件路径:", fileFullPath)
  162. if not os.path.exists(fileFullPath):
  163. print("文件不存在")
  164. return
  165. # app = xw.App(visible=True, add_book=False)
  166. # app.display_alerts = False
  167. # app.screen_updating = True
  168. # print("init app")
  169. if os.path.exists(fileFullPath) and ".xlsx" in fileFullPath \
  170. and fileFullPath.find("~$") < 0 \
  171. and fileFullPath.find("template") < 0:
  172. # 获取文件名和扩展名
  173. file_name, file_ext = os.path.splitext(os.path.basename(fileFullPath))
  174. file_name_ext = file_name + file_ext
  175. time.sleep(3)
  176. try:
  177. # 启动程序
  178. code = exePath + " " + fileFullPath
  179. # print(code)
  180. autoit.run(code)
  181. autoit.win_wait_active(file_name_ext, timeout=20) # 等待窗口激活
  182. autoit.win_move(file_name_ext, 0, 0, 1024, 768)
  183. # autoit.win_move(file_name_ext, 0, 0, 1920, 1080)
  184. # print("监听成功了")
  185. except Exception as e:
  186. print("监听", fileFullPath, "失败:", e)
  187. ## 失败的话,截图记录下原因
  188. screenshot = pyautogui.screenshot()
  189. imgPath = datetime.datetime.now().strftime("%Y%m%d%H%M%S") + "_screenshot_img.png"
  190. screenshot.save(imgPath)
  191. hwnd = win32gui.GetForegroundWindow()
  192. found_title = win32gui.GetWindowText(hwnd)
  193. print("当前窗口名称:", found_title)
  194. if found_title == "":
  195. print("窗口未打开")
  196. return
  197. # 遍历异常名称列表去校验,如果匹配上了,那么就要退出excel并打开
  198. for err_windows_name in err_windows_name_list:
  199. if found_title.startswith(err_windows_name):
  200. # 获取与窗口句柄关联的进程ID
  201. process_id = win32process.GetWindowThreadProcessId(hwnd)[1]
  202. # 根据进程ID获取进程对象并尝试优雅地终止进程
  203. target_process = psutil.Process(process_id)
  204. target_process.terminate()
  205. print("可能是EXCEL崩溃导致,优雅退出EXCEL")
  206. return
  207. # 如果是office的,那么就是要将file_name_ext变更为 file_name;因为office没有后缀
  208. if found_title.startswith(file_name_ext) == False:
  209. print("当前窗口与excel不一致,当前窗口:", found_title, ";excel:", file_name_ext)
  210. return
  211. autoit.win_move_by_handle(hwnd, 0, 0, 1024, 768)
  212. ## 屏幕最大化
  213. # open full screen
  214. # hwnd = win32gui.GetForegroundWindow()
  215. # win32gui.ShowWindow(hwnd, win32con.SW_MAXIMIZE)
  216. # time.sleep(1)
  217. # 停留一秒,让屏幕改变到正常大小
  218. time.sleep(1)
  219. ### 随机2-3次点击 单元格区域
  220. r = random.randint(2, 3)
  221. for i in range(r):
  222. pointX = random.randint(minPointX, maxPointX)
  223. pointY = random.randint(minPointY, maxPointY)
  224. print("随机点击", i + 1, "下")
  225. pyautogui.moveTo(pointX, pointY, 0.5)
  226. pyautogui.click()
  227. ## 随机停留几秒
  228. r = random.randint(1, 2)
  229. time.sleep(r)
  230. ##点击 红桃3 按钮
  231. pyautogui.moveTo(hongTao3PointX, hongTao3PointY, 0.5)
  232. pyautogui.click()
  233. time.sleep(1)
  234. ##点击 数据刷新 按钮
  235. pyautogui.moveTo(refreshButtonPointX, refreshButtonPointY, 0.5)
  236. pyautogui.click()
  237. time.sleep(1)
  238. ##点击 刷新工作簿 按钮
  239. print("开始刷新了")
  240. pyautogui.moveTo(refreshSheetPointX, refreshSheetPointY, 0.5)
  241. pyautogui.click()
  242. time.sleep(0.5)
  243. ## 校验登录失效
  244. # checkLoginInvalid()
  245. ## 校验重新登录
  246. checkHongtaoLoginButton()
  247. # 点击完刷新按钮后,移开鼠标
  248. pyautogui.moveTo(622, 300, 0.5)
  249. # 等待刷新结束
  250. # time.sleep(15)
  251. checkRefreshEnd()
  252. # # 完成了,点击结束
  253. # pointX = 1072
  254. # pointY = 605
  255. # pyautogui.moveTo(pointX, pointY, 0.5)
  256. # pyautogui.click()
  257. # time.sleep(0.5)
  258. # 保存
  259. pyautogui.hotkey('ctrl', 's')
  260. time.sleep(1)
  261. # 关闭当前excel
  262. pyautogui.hotkey('ctrl', 'w')
  263. return True
  264. else:
  265. print("ext err:" + fileFullPath)
  266. # app.kill()
  267. return True
  268. except Exception as e:
  269. print("Exception:")
  270. print(str(e))
  271. return False
  272. if __name__ == "__main__":
  273. app = __hug__.http.server()
  274. # server="waitress" 这个是因为有些windows的主机名有中文,需要换个服务器适配器
  275. run(app=app, host="0.0.0.0", reloader=True, port=7007, server="waitress")
  276. # http://127.0.0.1:7007/hongtao/refresh?FilePath=D:/eta/data/hongtao3_data/卓创数据统计.xlsx