PyAutoGUI结合线程实现Google Drive令牌自动刷新失败排查
问题分析与解决方案
核心问题排查
以下几个代码错误是导致线程失效、程序冻结的主要原因:
- 线程参数传递错误
创建clicker_thread时,args=(Drive)不是合法的元组,Python会把单个元素的括号当成表达式,实际传入的是Drive本身而非元组。正确写法必须加逗号:
clicker_thread = threading.Thread(target=TokenClicker, args=(Drive,))
- 未定义变量
chaineTokenClicker函数里用chaine做判断,但函数参数是Drive,完全不对应,应该用传入的Drive参数做逻辑判断:
def TokenClicker(Drive): time.sleep(2) if Drive == "Drive1": coordonees = pyautogui.locateOnScreen("TokenClicker/Email1.png") elif Drive == "Chain": print("Drive2") coordonees = pyautogui.locateOnScreen("TokenClicker/Email2.png") else: print("未知Drive类型") return
- 缺少异常与存在性判断
pyautogui.locateOnScreen找不到图片会返回None,直接调用moveTo(None)会抛出异常,导致线程直接终止,后续点击操作无法执行,令牌刷新窗口会一直等待交互,程序看起来像是冻结。必须增加判断:
# 查找邮箱图片时 coordonees = pyautogui.locateOnScreen("TokenClicker/Email1.png") if not coordonees: print("未找到邮箱图片") return pyautogui.moveTo(coordonees) # 后续的continue图片同理,都要做是否找到的判断
- 线程join顺序问题
你先执行token_thread.join(),会阻塞主线程直到令牌刷新完成,但如果点击线程因为前面的错误没执行,run_local_server会一直等待用户输入,导致主线程卡死。可以调整join顺序,或给join设置超时:
clicker_thread.join(timeout=15) token_thread.join(timeout=20)
修正后的完整代码示例
import threading import time import pyautogui from google_auth_oauthlib.flow import InstalledAppFlow def runtoken(credentials, scopes): flow = InstalledAppFlow.from_client_secrets_file(credentials, scopes) flow.run_local_server(port=0) def TokenClicker(Drive): time.sleep(2) coordonees = None # 用传入的Drive参数替换未定义的chaine if Drive == "Drive1": coordonees = pyautogui.locateOnScreen("TokenClicker/Email1.png") elif Drive == "Chain": print("Drive2") coordonees = pyautogui.locateOnScreen("TokenClicker/Email2.png") else: print(f"不支持的Drive类型: {Drive}") return if not coordonees: print("未找到邮箱选择图片") return pyautogui.moveTo(coordonees) pyautogui.leftClick() time.sleep(1) # 处理第一个continue按钮 coordonees = pyautogui.locateOnScreen("TokenClicker/continue1.png") if not coordonees: print("未找到第一个continue按钮") return pyautogui.moveTo(coordonees) time.sleep(1) pyautogui.leftClick() time.sleep(1) # 处理第二个continue按钮 coordonees = pyautogui.locateOnScreen("TokenClicker/continue2.png") if not coordonees: print("未找到第二个continue按钮") return pyautogui.moveTo(coordonees) pyautogui.leftClick() time.sleep(1) pyautogui.hotkey("ctrl", "w") print("令牌刷新窗口已关闭") # 线程启动代码修正 token_thread = threading.Thread(target=runtoken, args=(credentials,SCOPES)) # 注意args后面的逗号 clicker_thread = threading.Thread(target=TokenClicker, args=(Drive,)) clicker_thread.start() token_thread.start() # 设置超时避免主线程无限阻塞 clicker_thread.join(timeout=15) token_thread.join(timeout=20) print("Should be good")
额外注意事项
- Parsec远程桌面下,确保关闭系统分辨率缩放,避免PyAutoGUI识别图片时出现偏差;也可以用
pyautogui.screenshot()手动截图,对比确认识别用的图片是否和当前屏幕元素匹配。 - 尽量用绝对路径指定图片位置,避免因程序运行目录变化导致路径错误。
内容的提问来源于stack exchange,提问作者La Poubelle
相关产品推荐
相关产品推荐

