Explorar o código

Merge remote-tracking branch 'origin/master'

Roc hai 1 ano
pai
achega
cd143845af
Modificáronse 8 ficheiros con 793 adicións e 15 borrados
  1. 106 0
      hongtao3_login.py
  2. 86 0
      mail.py
  3. 87 0
      mail_xiangyu.py
  4. 17 11
      metting.py
  5. 3 4
      pb_api.py
  6. 203 0
      rpa_baiinfo_refresh.py
  7. 250 0
      rpa_hongtao3_refresh.py
  8. 41 0
      ths_api.py

+ 106 - 0
hongtao3_login.py

@@ -0,0 +1,106 @@
+import os
+import pythoncom
+import time
+import random
+import pyautogui
+import win32gui, win32con
+
+from apscheduler.schedulers.blocking import BlockingScheduler
+
+# FilePath = "‪E:\\hz\\hongtao3_data\\"
+FilePath = "E:\\hz\\hongtao3_data\\"
+# FilePath = "D:\\"
+FileName = "login.xlsx"
+
+def check_excel_is_open():
+    fileName = FilePath+FileName
+    fileName = fileName.replace(r"\\", "\\")
+    print(fileName)
+    if os.path.exists(fileName):
+        try:
+            oldName = FilePath + FileName
+            newName = FilePath + "tempfile.xls"
+            print(oldName)
+            print(newName)
+            os.rename(oldName, newName)
+            os.rename(newName, oldName)
+            return False
+        except OSError:
+            print('login excel opened')
+            return True
+        return True
+    else:
+        print("file is not exist")
+        return False
+
+
+def LoginFile(test):
+    loginStatus = check_excel_is_open()
+    print("loginStatus")
+    print(loginStatus)
+    if loginStatus is True:  # login 文件打开状态
+        print("loginStatus")
+        print(loginStatus)
+    else:
+        try:
+            # 回到桌面
+            pyautogui.hotkey('win', 'd')
+            time.sleep(1)
+
+            pythoncom.CoInitialize()
+            os.system("start " + FilePath + FileName)
+            time.sleep(3)
+            # et.dataBtn()
+
+            # 最大化
+            hwnd = win32gui.GetForegroundWindow()
+            win32gui.ShowWindow(hwnd, win32con.SW_MAXIMIZE)
+            time.sleep(1)
+
+            # 随机暂停秒数
+            r = random.randint(1, 3)
+            time.sleep(r)
+
+            print("点击了红桃三的按钮")
+            ## 点击 红桃三的按钮
+            #pointX = 595
+            pointX = 521
+            pointY = 42
+            pyautogui.moveTo(pointX, pointY, 0.5)
+            pyautogui.click(pointX, pointY)
+
+
+            ## 点击登录按钮
+            print("点击了登录按钮")
+            r = random.randint(1, 2)
+            time.sleep(r)
+            pointX = 503
+            pointY = 81
+            pyautogui.moveTo(pointX, pointY, 0.5)
+            pyautogui.click(pointX, pointY)
+
+            ## 点击同花顺的登录弹框按钮
+            print("点击了同花顺的登录弹框按钮")
+            r = random.randint(1, 2)
+            time.sleep(r)
+            pointX = 970
+            pointY = 574
+            pyautogui.moveTo(pointX, pointY, 0.5)
+            pyautogui.click(pointX, pointY)
+            time.sleep(1)
+
+
+        except Exception as e:
+            print("open err")
+            print(str(e))
+
+
+if __name__ == '__main__':
+    # check_excel_is_open()
+
+    scheduler = BlockingScheduler()
+    scheduler.add_job(LoginFile, 'interval', seconds=20, args=['job1'], timezone='Asia/Shanghai')
+    try:
+        scheduler.start()
+    except (KeyboardInterrupt, SystemExit):
+        pass

+ 86 - 0
mail.py

@@ -0,0 +1,86 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import poplib
+import datetime
+import time
+from email.parser import Parser
+from email.header import decode_header
+
+# 输入邮件地址, 口令和POP3服务器地址:
+email = ''
+password = '' # 注意使用开通POP,SMTP等的授权码
+pop3_server = 'pop.qiye.aliyun.com'
+
+
+def decode_str(s):  # 字符编码转换
+    value, charset = decode_header(s)[0]
+    if charset:
+        value = value.decode(charset)
+    return value
+
+
+def get_att(msg):
+    import email
+    attachment_files = []
+
+    for part in msg.walk():
+        file_name = part.get_filename()  # 获取附件名称类型
+        contType = part.get_content_type()
+        print(file_name)
+        if file_name:
+            h = email.header.Header(file_name)
+            dh = email.header.decode_header(h)  # 对附件名称进行解码
+            filename = dh[0][0]
+            if dh[0][1]:
+                filename = decode_str(str(filename, dh[0][1]))  # 将附件名称可读化
+                print(filename)
+                # filename = filename.encode("utf-8")
+            data = part.get_payload(decode=True)  # 下载附件
+            att_file = open('/home/code/python/coal_mail/emailFile/' + filename, 'wb')  # 在指定目录下创建文件,注意二进制文件需要用wb模式打开
+            attachment_files.append(filename)
+            att_file.write(data)  # 保存附件
+            att_file.close()
+    return attachment_files
+
+
+# 连接到POP3服务器,有些邮箱服务器需要ssl加密,对于不需要加密的服务器可以使用poplib.POP3()
+server = poplib.POP3_SSL(pop3_server)
+server.set_debuglevel(1)
+# 打印POP3服务器的欢迎文字:
+print(server.getwelcome().decode('utf-8'))
+# 身份认证:
+server.user(email)
+server.pass_(password)
+# 返回邮件数量和占用空间:
+print('Messages: %s. Size: %s' % server.stat())
+# list()返回所有邮件的编号:
+resp, mails, octets = server.list()
+# 可以查看返回的列表类似[b'1 82923', b'2 2184', ...]
+print(mails)
+index = len(mails)
+print(index)
+for i in range(index, 0, -1):
+    # 倒序遍历邮件
+    resp, lines, octets = server.retr(i)
+    # lines存储了邮件的原始文本的每一行,
+    # 邮件的原始文本:
+    msg_content = b'\r\n'.join(lines).decode('utf-8')
+    # 解析邮件:
+    msg = Parser().parsestr(msg_content)
+    # 获取邮件时间
+    date1 = time.strptime(msg.get("Date")[0:24], '%a, %d %b %Y %H:%M:%S')  # 格式化收件时间
+    date2 = time.strftime("%Y%m%d", date1)  # 邮件时间格式转换
+    now_time = datetime.datetime.now()
+    # // 自定义下载附件时间范围
+    getFileDay = (now_time + datetime.timedelta(days=-1)).strftime("%Y%m%d")
+    # 邮件最早的时间
+    print(date1)
+    # 邮件最近的时间
+    print(date2)
+    if date2 < getFileDay:
+        continue
+    f_list = get_att(msg)  # 获取附件
+    # print_info(msg)
+
+server.quit()
+

+ 87 - 0
mail_xiangyu.py

@@ -0,0 +1,87 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import poplib
+import datetime
+import time
+from email.parser import Parser
+from email.header import decode_header
+
+# 输入邮件地址, 口令和POP3服务器地址:
+email = ''
+password = '' # 注意使用开通POP,SMTP等的授权码
+pop3_server = 'pop3.xiangyu.cn'
+
+
+def decode_str(s):  # 字符编码转换
+    value, charset = decode_header(s)[0]
+    if charset:
+        value = value.decode(charset)
+    return value
+
+
+def get_att(msg):
+    import email
+    attachment_files = []
+
+    for part in msg.walk():
+        file_name = part.get_filename()  # 获取附件名称类型
+        contType = part.get_content_type()
+        print(file_name)
+        if file_name:
+            h = email.header.Header(file_name)
+            dh = email.header.decode_header(h)  # 对附件名称进行解码
+            filename = dh[0][0]
+            if dh[0][1]:
+                filename = decode_str(str(filename, dh[0][1]))  # 将附件名称可读化
+                print(filename)
+                # filename = filename.encode("utf-8")
+            data = part.get_payload(decode=True)  # 下载附件
+#             att_file = open('/home/code/python/coal_mail/emailFile/' + filename, 'wb')  # 在指定目录下创建文件,注意二进制文件需要用wb模式打开
+            att_file = open('/Users/xi/Desktop/coal_mail/emailFile/' + filename, 'wb')  # 在指定目录下创建文件,注意二进制文件需要用wb模式打开
+            attachment_files.append(filename)
+            att_file.write(data)  # 保存附件
+            att_file.close()
+    return attachment_files
+
+
+# 连接到POP3服务器,有些邮箱服务器需要ssl加密,对于不需要加密的服务器可以使用poplib.POP3()
+server = poplib.POP3_SSL(pop3_server,'995')
+server.set_debuglevel(1)
+# 打印POP3服务器的欢迎文字:
+print(server.getwelcome().decode('utf-8'))
+# 身份认证:
+server.user(email)
+server.pass_(password)
+# 返回邮件数量和占用空间:
+print('Messages: %s. Size: %s' % server.stat())
+# list()返回所有邮件的编号:
+resp, mails, octets = server.list()
+# 可以查看返回的列表类似[b'1 82923', b'2 2184', ...]
+print(mails)
+index = len(mails)
+print(index)
+for i in range(index, 0, -1):
+    # 倒序遍历邮件
+    resp, lines, octets = server.retr(i)
+    # lines存储了邮件的原始文本的每一行,
+    # 邮件的原始文本:
+    msg_content = b'\r\n'.join(lines).decode('utf-8')
+    # 解析邮件:
+    msg = Parser().parsestr(msg_content)
+    # 获取邮件时间
+    date1 = time.strptime(msg.get("Date")[0:24], '%a, %d %b %Y %H:%M:%S')  # 格式化收件时间
+    date2 = time.strftime("%Y%m%d", date1)  # 邮件时间格式转换
+    now_time = datetime.datetime.now()
+    # // 自定义下载附件时间范围
+    getFileDay = (now_time + datetime.timedelta(days=-1)).strftime("%Y%m%d")
+    # 邮件最早的时间
+    print(date1)
+    # 邮件最近的时间
+    print(date2)
+    if date2 < getFileDay:
+        continue
+    f_list = get_att(msg)  # 获取附件
+    # print_info(msg)
+
+server.quit()
+

+ 17 - 11
metting.py

@@ -6,7 +6,7 @@ import openpyxl
 from selenium import webdriver
 
 # 设置Chrome浏览器选项
-from selenium.common import exceptions
+from selenium.common import exceptions, NoSuchElementException, ElementNotInteractableException
 from selenium.webdriver.chrome.service import Service
 from selenium.webdriver.common.by import By
 from selenium.webdriver.support import expected_conditions as EC
@@ -109,15 +109,18 @@ if __name__ == "__main__":
     text = driver.find_element(By.XPATH, '//*[@id="page_default_sections"]/div/div/div/div/div/p[1]/span')
     print("网页中段,文本内容:")
     print(text.text)
-
-    btn_pop = get_element(driver, '/html/body/div[4]/div[3]/div/section/span')
-    if btn_pop:
-        btn_pop.click()
-
-    accept_btn = get_element(driver, '//*[@id="onetrust-accept-btn-handler"]')
-    if accept_btn:
-        accept_btn.click()
-
+    try:
+        btn_pop = get_element(driver, '/html/body/div[4]/div[3]/div/section/span')
+        if btn_pop:
+            btn_pop.click()
+
+        accept_btn = get_element(driver, '//*[@id="onetrust-accept-btn-handler"]')
+        if accept_btn:
+            accept_btn.click()
+    except ElementNotInteractableException:
+        # 如果元素不存在,则隐藏报错并执行其他操作
+        print("元素不可点击")
+        ''
     WebDriverWait(driver, 10).until(
         EC.visibility_of_element_located((By.XPATH, '/html/body/main/div/div[4]/div/iframe')))  # iframe是否出现
 
@@ -129,8 +132,11 @@ if __name__ == "__main__":
     # button = driver.find_element(By.XPATH, '//*[@id="ctl00_MainContent_ucViewControl_IntegratedFedWatchTool_lbPTree"]')
     driver.execute_script(
         "javascript:__doPostBack('ctl00$MainContent$ucViewControl_IntegratedFedWatchTool$lbPTree','')")
-    sleep(2)
+
+    WebDriverWait(driver, 10).until(
+        EC.visibility_of_element_located((By.XPATH, '//*[@id="MainContent_pnlContainer"]/div[3]/div/div/table[2]')))
     table = driver.find_element(By.XPATH, '//*[@id="MainContent_pnlContainer"]/div[3]/div/div/table[2]')
+
     table.screenshot(r'meeting.png')
     print(table.text)
     # 按行查询表格的数据,取出的数据是一整行,按空格分隔每一列的数据

+ 3 - 4
pb_api.py

@@ -15,7 +15,7 @@ def hello():
 @hug.get('/edbInfo/pb')
 def GetEdbDataByPb(EdbCode, StartDate, EndDate):
     print("GetEdbDataByPb")
-    bbg = pdblp.BCon(debug=True, port=8194)
+    bbg = pdblp.BCon(debug=True, port=8194, timeout=10000)
     bbg.start()
     try:
         rst = bbg.bdh(EdbCode,
@@ -43,7 +43,7 @@ def GetEdbDataByPbFinance(CompanyCode, EdbCode, StartDate, EndDate):
     try:
         # rst = bbg.bdh(CompanyCode, EdbCode, StartDate, EndDate, longdata=True).to_json()
         print("start get data")
-       # rst = bbg.bdh(CompanyCode, EdbCode, '20200701', '20221231', longdata=True)
+        # rst = bbg.bdh(CompanyCode, EdbCode, '20200701', '20221231', longdata=True)
         rst = bbg.bdh(CompanyCode, EdbCode, StartDate, EndDate, longdata=True)
         print(rst)
         print("end get data")
@@ -66,7 +66,6 @@ def GetEdbDataByPbFinance(CompanyCode, EdbCode, StartDate, EndDate):
         return
 
 
-
 if __name__ == "__main__":
     app = __hug__.http.server()
-    run(app=app, reloader=True,host='0.0.0.0', port=7001)
+    run(app=app, reloader=True, host='0.0.0.0', port=7001)

+ 203 - 0
rpa_baiinfo_refresh.py

@@ -0,0 +1,203 @@
+import hug
+from bottle import route, run
+import pyautogui
+import random
+import time
+import os
+import win32gui, win32con
+import autoit
+import pyperclip
+import pythoncom
+import datetime
+
+hug.API(__name__).http.output_format = hug.output_format.json
+
+exePath = r"C:\Program Files (x86)\Kingsoft\WPS Office\11.8.2.12085\office6\et"
+# exePath = exePath = r"C:\Program Files (x86)\Microsoft Office\root\Office16\EXCEL.EXE"
+# exePath = exePath = r"C:\Program Files\Microsoft Office\root\Office16\EXCEL.EXE"
+
+
+# 顶部百川按钮的x,y位置
+top_refresh_button_x = 645
+top_refresh_button_y = 45
+
+# 百川选项卡下面的刷新按钮的x,y位置
+real_refresh_button_x = 302
+real_refresh_button_y = 87
+
+# 获取数据的超时时间(单位:s)
+get_data_timeout_time = 30
+
+# 随机点击的按钮范围
+pointMinX = 200
+pointMaxX = 650
+pointMinY = 300
+pointMaxY = 550
+
+
+@hug.get('/baiinfo/server')
+def baiinfo_server():
+    return 1
+
+
+@hug.get('/baiinfo/refresh')
+def baiinfo_refresh(file_path):
+    screen_width, screen_height = pyautogui.size()
+    print("屏幕分辨率:{} x {}".format(screen_width, screen_height))
+
+    pyautogui.FAILSAFE = False
+    # file_path = urllib.parse.unquote(file_path)
+    file_path = file_path.replace('"', '')
+
+    pyautogui.hotkey('win', 'd')
+    # time.sleep(2)
+    #
+    # moveX = 1100
+    # moveY = 600
+    # pyautogui.moveTo(moveX, moveY, 0.5)
+    # pyautogui.click(moveX, moveY)
+    try:
+        fileFullPath = file_path
+        print("fileFullPath start")
+        # print(fileFullPath)
+
+        fileFullPath = fileFullPath.replace("\\\\", "\\")
+
+        # fileFullPath.replace("\\", "\\")
+        # fileFullPath.replace("ppp", "")
+
+        # print("fileFullPath")
+        print(fileFullPath)
+
+        # app = xw.App(visible=True, add_book=False)
+        # app.display_alerts = False
+        # app.screen_updating = True
+        # print("init app")
+        if os.path.exists(fileFullPath) and ".xlsx" in fileFullPath \
+                and fileFullPath.find("~$") < 0 \
+                and fileFullPath.find("template") < 0:
+
+            # 获取文件名和扩展名
+            file_name, file_ext = os.path.splitext(os.path.basename(fileFullPath))
+            file_name_ext = file_name + file_ext
+            print(file_name_ext)
+            print(datetime.datetime.now())
+
+            try:
+                # 打开文件
+                # pythoncom.CoInitialize()
+                # pyautogui.hotkey('win','r')
+                # pyautogui.sleep(0.5)
+                # time.sleep(2)
+                # pyperclip.copy(fileFullPath)
+                # pyautogui.hotkey('ctrl', 'v')
+                # pyautogui.keyDown('enter')
+                # pyautogui.keyUp('enter')
+                # time.sleep(5)
+                #
+                # # open full screen
+                # hwnd = win32gui.GetForegroundWindow()
+                # win32gui.ShowWindow(hwnd, win32con.SW_MAXIMIZE)
+                # time.sleep(1)
+
+                # 启动程序
+                code = exePath + " " + fileFullPath
+                # print(code)
+                autoit.run(code)
+                autoit.win_wait_active(file_name_ext, timeout=20)  # 等待窗口激活
+                autoit.win_move(file_name_ext, 0, 0, 1024, 768)
+                # autoit.win_move(file_name_ext, 0, 0, 1920, 1080)
+
+                print("监听成功了")
+
+            except Exception as e:
+                print("打开", fileFullPath, "失败:", e)
+
+                ## 失败的话,截图记录下原因
+                screenshot = pyautogui.screenshot()
+                imgPath = datetime.datetime.now().strftime("%Y%m%d%H%M%S") + "_screenshot_img.png"
+                screenshot.save(imgPath)
+
+                hwnd = win32gui.GetForegroundWindow()
+                found_title = win32gui.GetWindowText(hwnd)
+                print("窗口名称:", found_title)
+                if found_title == "":
+                    print("窗口未打开")
+                    return
+                if found_title.startswith(file_name_ext) == False:
+                    print("窗口与excel不一致,当前窗口:", found_title, ";excel:", file_name_ext)
+                    return
+                autoit.win_move_by_handle(hwnd, 0, 0, 1024, 768)
+                # autoit.win_move_by_handle(hwnd, 0, 0, 1920, 1080)
+
+            ### 随机2-3次点击 单元格区域(每次点击停留1s)
+            r = random.randint(2, 3)
+            for i in range(r):
+                pointX = random.randint(pointMinX, pointMaxX)
+                pointY = random.randint(pointMinY, pointMaxY)
+                print("随机点击", i + 1, "下;", "点击X:", pointX, ";Y:", pointY)
+                pyautogui.moveTo(pointX, pointY, 0.5)
+                pyautogui.click()
+                time.sleep(1)
+
+            print("start dataBtn")
+            pyautogui.moveTo(top_refresh_button_x, top_refresh_button_y, 0.5)
+            pyautogui.click()
+            time.sleep(2)
+            print("end dataBtn")
+
+            pointX = random.randint(pointMinX, pointMaxX)
+            pointY = random.randint(pointMinY, pointMaxY)
+            pyautogui.moveTo(pointX, pointY)
+            pyautogui.click()
+            print("点击X:", pointX, ";Y:", pointY)
+
+            # 停留随机秒数
+            sleepSec = random.randint(1, 3)
+            time.sleep(sleepSec)
+
+            pointX = random.randint(pointMinX, pointMaxX)
+            pointY = random.randint(pointMinY, pointMaxY)
+            pyautogui.moveTo(pointX, pointY)
+            pyautogui.click()
+            print("点击X:", pointX, ";Y:", pointY)
+            # 停留随机秒数
+            sleepSec = random.randint(1, 3)
+            time.sleep(sleepSec)
+
+            print("start getCurrentPageData")
+            pyautogui.moveTo(real_refresh_button_x, real_refresh_button_y, 1)
+            pyautogui.click()
+            time.sleep(1)
+
+            print("end getCurrentPageData")
+
+            pointX = random.randint(pointMinX, pointMaxX)
+            pointY = random.randint(pointMinY, pointMaxY)
+            pyautogui.moveTo(pointX, pointY, 0.5)
+            pyautogui.click()
+            print("点击X:", pointX, ";Y:", pointY)
+            # 停留等待数据更新
+            time.sleep(get_data_timeout_time)
+
+            pyautogui.hotkey('ctrl', 's')
+            time.sleep(1)
+            pyautogui.hotkey('ctrl', 'w')
+
+            return True
+            # wb.save()
+            #
+            # wb.close()
+        else:
+            print("ext err:" + fileFullPath)
+        # app.kill()
+        return True
+    except Exception as e:
+        print("Exception:")
+        print(str(e))
+        return False
+
+
+if __name__ == "__main__":
+    app = __hug__.http.server()
+    run(app=app, reloader=True, host='0.0.0.0', port=7007)

+ 250 - 0
rpa_hongtao3_refresh.py

@@ -0,0 +1,250 @@
+import hug
+from bottle import route, run
+import pyautogui
+import random
+import time
+import os
+import pythoncom
+import win32gui, win32con, win32process
+import psutil
+import urllib.parse
+import subprocess
+
+hug.API(__name__).http.output_format = hug.output_format.json
+
+
+def getProcessName(hwnd):
+    tid, pid = win32process.GetWindowThreadProcessId(hwnd)
+    processName = psutil.Process(pid).name()
+    return processName
+
+
+def getClassName(hwnd):
+    className = win32gui.GetClassName(hwnd)
+    return className
+
+
+## 获取窗口标题
+def getText(hwnd):
+    text = win32gui.GetWindowText(hwnd)
+    return text
+
+
+# 检验卓创的登录失效按钮
+def checkLoginInvalid():
+    # 登录失效的弹框(类名: Button)
+    pointX = 1047
+    pointY = 604
+    hwnd = win32gui.WindowFromPoint((pointX, pointY))
+    # print("检验卓创的登录失效按钮:", hwnd)
+    if hwnd != 0:
+        print("检验卓创的登录失效按钮:processName:", getProcessName(hwnd), ",类名:", getClassName(hwnd))
+        if getProcessName(hwnd) == "EXCEL.EXE" and getClassName(hwnd) == "Button":
+            print("好吧,登录失效了")
+            pyautogui.moveTo(pointX, pointY, 0.5)
+            pyautogui.click()
+            time.sleep(1)
+            return True
+        else:
+            return False
+    else:
+        return False
+
+
+# 检验卓创的登录按钮
+def checkHongtaoLoginButton():
+    # 卓创登录的弹框(类名: WindowsForms10.BUTTON.app.0.182b0e9_r93_ad2)
+    pointX = 1042
+    pointY = 564
+    hwnd = win32gui.WindowFromPoint((pointX, pointY))
+    # print("检验卓创的登录按钮:", hwnd)
+    if hwnd != 0:
+        className = getClassName(hwnd)
+        print("检验卓创的登录按钮:processName:", getProcessName(hwnd), ",类名:", className)
+        lenClassName = len(className)
+        # if getProcessName(hwnd) == "EXCEL.EXE" and getClassName(hwnd) == "WindowsForms10.BUTTON.app.0.182b0e9_r93_ad2":
+        if getProcessName(hwnd) == "EXCEL.EXE" and className != "Button":
+            print("开始卓创登录")
+            pyautogui.moveTo(pointX, pointY, 0.5)
+            pyautogui.click()
+            time.sleep(1)
+            return True
+        else:
+            return False
+    else:
+        return False
+
+
+# 检验卓创的数据刷新组件
+def checkRefreshEnd():
+    # 登录失效的弹框(类名: Button)
+    # 完成了,点击结束
+    pointX = 1072
+    pointY = 605
+
+    i = 1
+    n = 1
+    while i < 2:
+        hwnd = win32gui.WindowFromPoint((pointX, pointY))
+        # print("检验卓创的数据刷新组件:", hwnd)
+        print("第", n, "次检测")
+        n = n + 1
+        if hwnd != 0:
+            print("检验卓创的数据刷新组件:processName:", getProcessName(hwnd), ",类名:", getClassName(hwnd))
+            if getProcessName(hwnd) == "EXCEL.EXE" and getClassName(hwnd) == "Button":
+                print("ok,刷新完成了")
+                pyautogui.moveTo(pointX, pointY, 0.5)
+                pyautogui.click()
+                time.sleep(1)
+                return True
+            else:
+                ## 不用n=2的原因,是因为那个遮罩层可能没那么快出来,万一真实很快就被刷出来了,那么超时500s后,就超时关闭吧
+                if n >= 500 and getClassName(hwnd) == "EXCEL7":
+                    print("ok,应该是很快就刷新完成了")
+                    return True
+                time.sleep(1)
+        else:
+            return
+
+
+@hug.get('/hongtao/server')
+def mysteel_chemical_server():
+    return 1
+
+
+@hug.get('/hongtao/refresh')
+def mysteel_chemical_refresh(FilePath):
+    pyautogui.FAILSAFE = False
+    # FilePath = urllib.parse.unquote(FilePath)
+    FilePath = FilePath.replace('"', '')
+
+    pyautogui.hotkey('win', 'd')
+
+    # return "a"
+    try:
+        fileFullPath = FilePath
+        print("fileFullPath start")
+        print(fileFullPath)
+
+        fileFullPath = fileFullPath.replace(r"\\", "\\")
+        # fileFullPath = fileFullPath.replace("\\\\", "\\")
+
+        # print("fileFullPath:", fileFullPath)
+
+        if os.path.exists(fileFullPath) == False:
+            return
+
+        # app = xw.App(visible=True, add_book=False)
+        # app.display_alerts = False
+        # app.screen_updating = True
+        # print("init app")
+        if os.path.exists(fileFullPath) and ".xlsx" in fileFullPath \
+                and fileFullPath.find("~$") < 0 \
+                and fileFullPath.find("template") < 0:
+
+            ## 鼠标移动到左下角,开始搜索文件
+            # moveX = 22
+            # moveY = 1058
+            # pyautogui.moveTo(moveX, moveY, 0.5)
+            # pyautogui.click(moveX, moveY)
+            # time.sleep(2)
+            # pyautogui.typewrite(fileFullPath, 0.1)
+            # # print("open file:" + fileFullPath)
+            # # wb = app.books.open(fileFullPath)
+            # pyautogui.keyDown('enter')
+            # pyautogui.keyUp('enter')
+            # pyautogui.keyDown('enter')
+            # pyautogui.keyUp('enter')
+
+            # 打开文件
+            pythoncom.CoInitialize()
+            # openStatus = os.system("start " + fileFullPath.strip())
+            openStatus = os.system('start "" "{}"'.format(fileFullPath))
+            # 在上面的代码中,使用双引号将文件名引用为一个整体,这可以确保 Windows 命令行正确解释带有空格的文件路径。os.system()函数将启动一个新的命令行窗口来运行命令,然后等待命令完成。在这种情况下,"start " 命令告诉 Windows 打开文件,并使用双引号将文件名引用为一个整体。
+
+            # print("openStatus:", openStatus)
+            if openStatus == 1:
+                return False
+            time.sleep(3)
+
+            ## 屏幕最大化
+            # open full screen
+            hwnd = win32gui.GetForegroundWindow()
+            win32gui.ShowWindow(hwnd, win32con.SW_MAXIMIZE)
+            time.sleep(1)
+
+            ### 随机2-3次点击 单元格区域
+            r = random.randint(2, 3)
+            for i in range(r):
+                pointX = random.randint(511, 1745)
+                pointY = random.randint(282, 791)
+                print("随机点击", i + 1, "下")
+                pyautogui.moveTo(pointX, pointY, 0.5)
+                pyautogui.click()
+
+            ## 随机停留几秒
+            r = random.randint(1, 2)
+            time.sleep(r)
+
+            ##点击 红桃3 按钮
+            # pointX = 641
+            # pointX = 590
+            pointX = 521
+            pointY = 42
+            pyautogui.moveTo(pointX, pointY, 0.5)
+            pyautogui.click()
+            time.sleep(1)
+            ##点击 数据刷新 按钮
+            pointX = 199
+            pointY = 78
+            pyautogui.moveTo(pointX, pointY, 0.5)
+            pyautogui.click()
+            time.sleep(1)
+            ##点击 刷新工作簿 按钮
+            print("开始刷新了")
+            pointX = 226
+            pointY = 169
+            pyautogui.moveTo(pointX, pointY, 0.5)
+            pyautogui.click()
+            time.sleep(0.5)
+
+            ## 校验登录失效
+            checkLoginInvalid()
+
+            ## 校验重新登录
+            checkHongtaoLoginButton()
+
+            # 点击完刷新按钮后,移开鼠标
+            pyautogui.moveTo(622, 300, 0.5)
+
+            # 等待刷新结束
+            # time.sleep(15)
+            checkRefreshEnd()
+
+            # # 完成了,点击结束
+            # pointX = 1072
+            # pointY = 605
+            # pyautogui.moveTo(pointX, pointY, 0.5)
+            # pyautogui.click()
+            # time.sleep(0.5)
+
+            # 保存
+            pyautogui.hotkey('ctrl', 's')
+            time.sleep(1)
+            # 关闭当前excel
+            pyautogui.hotkey('ctrl', 'w')
+
+            return True
+        else:
+            print("ext err:" + fileFullPath)
+        # app.kill()
+        return True
+    except Exception as e:
+        print("Exception:")
+        print(str(e))
+        return False
+
+
+if __name__ == "__main__":
+    app = __hug__.http.server()
+    run(app=app, reloader=True, port=7007)

+ 41 - 0
ths_api.py

@@ -61,6 +61,47 @@ def GetFutureGoodEdbDataByThs(EdbCode, StartDate, EndDate):
     print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + ":end GetFutureGoodEdbDataByThs")
     return result
 
+def ths_data_to_dict(ths_instance):
+    if ths_instance is not None and ths_instance.data is not None:
+        return {
+            'errorcode': ths_instance.errorcode,
+            'errmsg': ths_instance.errmsg,
+            'data': ths_instance.data.to_dict(orient='records')
+        }
+    else:
+        # 处理 ths_instance 为 None 的情况
+        return {
+            'errorcode': 'N/A',
+            'errmsg': 'N/A',
+            'data': []
+        }
+
+def has_comma(input_string):
+    return isinstance(input_string, str) and ',' in input_string
+
+def process_single_edb_code(StockCode, SingleEdbCode, StartDate, EndDate):
+    thsEDBDataQuery = THS.THS_DS(StockCode, SingleEdbCode, '', '', StartDate, EndDate)
+    print(thsEDBDataQuery)
+    result = json.dumps(ths_data_to_dict(thsEDBDataQuery))
+    return result
+
+@hug.get('/edbInfo/ths/ds')
+def GetEdbDataByThsDs(StockCode, EdbCode, StartDate, EndDate):
+    print("THS_DataSequence start")
+    print(EdbCode)
+    result_list = []
+
+    if isinstance(EdbCode, list):
+        for SingleEdbCode in EdbCode:
+            result_list.append(process_single_edb_code(StockCode, SingleEdbCode, StartDate, EndDate))
+            print("THS_DS end")
+        print(result_list)
+        return result_list
+    else:
+        # 如果不包含逗号,直接处理
+        result = process_single_edb_code(StockCode, EdbCode, StartDate, EndDate)
+        print(result)
+        return result
 
 if __name__ == "__main__":
     # ths登录函数