Python自动化方案:解决Cursor Pro ChatGPT Token过期与保活难题
在软件开发与AI编程工具深度集成的背景下,自动化凭证管理与状态维持成为提升开发效率的关键技术。其核心原理是通过脚本模拟用户操作与网络请求,实现系统登录、令牌获取与客户端保活的自动化流程。这项技术的价值在于将开发者从重复性手动操作中解放,保障开发环境的连续性与稳定性,尤其适用于需要长期保持会话状态的AI辅助编程场景。通过Python生态的requests、selenium等库,结合微软Graph A
1. 项目概述与核心价值
最近在折腾AI编程工具,发现Cursor这个基于GPT的IDE确实好用,但它的Pro版本有个让人头疼的限制:需要关联一个有效的ChatGPT账号,并且这个账号的登录状态(Access Token)会过期。一旦Token失效,Cursor Pro的高级功能就停摆了,非常影响深度开发时的连续性。手动去ChatGPT网页端登录刷新Token,不仅麻烦,还经常打断思路。为了解决这个痛点,我花时间研究并整合了一套自动化方案,核心就是两个Python脚本:一个负责自动获取并刷新ChatGPT的Access Token,另一个负责确保Cursor Pro客户端保持“活跃”状态,从而间接维持Token的有效性。
这套工具的本质,是构建了一个本地化的、自动化的凭证管理与状态维持系统。它特别适合那些重度依赖Cursor Pro进行编码、且希望获得稳定无中断体验的开发者。你不用再担心写着写着代码,AI辅助突然消失。整个方案运行在你的本地环境或服务器上,完全自托管,不涉及修改任何Cursor客户端软件,安全性和可控性都更高。下面,我就把这套方案的实现思路、详细步骤以及我踩过的坑,毫无保留地分享出来。
2. 方案架构与核心组件解析
2.1 整体工作流程设计
整个自动化系统的运行逻辑是一个闭环。首先,我们需要一个稳定的“信源”来提供ChatGPT的登录凭证。这里我选择了微软别名邮箱(Outlook)作为接收验证码的渠道,因为它相对稳定,且可以通过API自动化操作。然后,核心脚本 gpt-accesstoken.py 会利用这些凭证,模拟浏览器行为登录ChatGPT,并提取出关键的Access Token。最后, cursor_pro_keep_alive.py 脚本会周期性地向Cursor Pro客户端发送模拟活动信号,使其保持在线状态,而Cursor Pro在活跃状态下会持续使用我们提供的有效Token,从而避免因Token过期导致的服务降级。
为什么选择这样的架构?直接去逆向Cursor客户端的通信协议来维持Token,不仅复杂而且可能违反用户协议。而通过维持客户端活跃这个“侧面”方式,是利用了Cursor Pro自身的设计逻辑——只要客户端在运行且活跃,它就会尽力维持当前会话。这种方式更间接,但也更安全、更稳定,不与官方机制直接冲突。
2.2 核心脚本功能拆解
-
gpt-accesstoken.py(Token获取器)- 核心任务 :自动化完成ChatGPT的登录流程,并捕获登录成功后返回的Access Token。
- 关键依赖 :
cursor_auth_manager.py。这个模块封装了登录的复杂逻辑,包括处理可能出现的验证码、人机验证(如Cloudflare Turnstile)等。后来的版本将其功能集成到了主脚本中,使得获取Token的过程更加一键化。 - 输出 :一个有效的Access Token字符串。这是整个系统的“燃料”。
-
cursor_pro_keep_alive.py(保活器)- 核心任务 :模拟用户活动,防止Cursor Pro客户端因长时间无操作而进入休眠或断开与后台服务的连接。
- 实现原理 :通常通过模拟鼠标移动、轻微的前台窗口切换,或者向Cursor进程发送特定的系统消息来实现。其目的不是“使用”AI功能,而是制造“用户在线”的假象。
- 运行模式 :一般作为后台守护进程运行,定时(例如每5-10分钟)执行一次保活动作。
-
mail_api.py与config.txt(辅助支撑系统)- 角色 :为
gpt-accesstoken.py提供自动化的验证码获取能力。 -
mail_api.py:一个封装了微软Graph API调用的模块,用于查询指定邮箱中的最新邮件,并提取验证码。这避免了人工查看邮箱的步骤。 -
config.txt:配置文件,集中存放敏感和可变的参数,例如:client_id和refresh_token: 用于微软API身份验证。- ChatGPT的登录账号和密码(注意:密码存储需谨慎,建议仅用于测试环境或配合环境变量)。
- 保活脚本的运行间隔时间。
- 安全提醒 :永远不要将包含真实密码和有效Token的
config.txt文件提交到Git等版本控制系统。务必将其添加到.gitignore文件中。
- 角色 :为
2.3 工具选型与替代方案探讨
- 为什么用Python? Python在自动化脚本、网络请求处理和桌面自动化方面有极其丰富的库(如
requests,selenium,pyautogui,pywin32等),社区资源丰富,快速原型开发能力强,是此类集成任务的理想选择。 - 邮箱选择的考量 :微软邮箱(Outlook/Hotmail)的Graph API比较规范,稳定可靠,并且支持创建别名,可以用一个主邮箱管理多个别名,非常适合这种自动化场景。如果不用邮箱API,也可以考虑使用临时手机号服务(SMS API),但成本更高且稳定性参差不齐。
- 保活方式的权衡 :模拟鼠标移动(
pyautogui)是最通用的,但会真实移动你的光标。发送系统消息或控制前台窗口更隐蔽,但Windows/macOS/Linux的实现方式不同,需要跨平台适配。我目前的脚本可能更偏向Windows环境(使用pywin32),Linux/macOS用户可能需要稍作修改,使用Quartz(macOS)或Xlib(Linux)等库。
3. 环境准备与详细配置指南
3.1 Python环境搭建与依赖安装
首先,确保你的系统安装了Python 3.8或更高版本。建议使用虚拟环境来隔离项目依赖,避免污染全局环境。
# 1. 克隆项目代码(假设项目已存在)
# git clone <repository-url> # 此处根据你的实际来源操作
# cd gpt-cursor-auto
# 2. 创建并激活虚拟环境(以venv为例)
python -m venv venv
# Windows:
venv\Scripts\activate
# Linux/macOS:
source venv/bin/activate
# 3. 安装项目依赖
# 你需要一个 requirements.txt 文件,或者手动安装核心包
pip install requests selenium pyautogui python-dotenv
# 如果用到微软Graph API,还需要
pip install msal
# 如果脚本涉及Windows GUI自动化,可能需要
pip install pywin32
注意 :
selenium需要对应的浏览器驱动(如ChromeDriver)。你需要根据本地Chrome版本下载匹配的驱动,并将其所在目录添加到系统PATH环境变量中。这是自动登录ChatGPT环节可能遇到的首要挑战。
3.2 微软邮箱API配置详解
这是实现全自动获取Token的关键一步。你需要让 mail_api.py 能够代表你读取邮箱中的验证码邮件。
-
注册Azure应用 :
- 访问 Azure门户 ,进入“Azure Active Directory”。
- 选择“应用注册”,点击“新注册”。
- 填写应用名称(如
CursorTokenFetcher),选择“仅此组织目录中的帐户”(单租户),重定向URI类型选择“Web”,值可以暂时填http://localhost:8080(仅用于获取授权码,后续脚本中不会真正启动服务)。 - 注册完成后,记下“应用程序(客户端) ID”,这就是你的
client_id。
-
配置API权限并获取Refresh Token :
- 在注册的应用页面,进入“API权限”,点击“添加权限”,选择“Microsoft Graph” -> “委托的权限”。
- 添加
Mail.Read权限(用于读取邮件)。如果你需要发送邮件(本场景不需要),还需添加Mail.Send。 - 管理员需要对此权限进行同意(如果是个人账户,通常自己就是管理员)。
- 接下来,你需要通过一次性的OAuth 2.0授权流程来获取
refresh_token。这通常需要一个简单的脚本或使用Postman等工具。核心是构造一个授权URL,让用户(你)登录并同意授权,然后回调地址会收到一个authorization_code,再用这个code去交换access_token和refresh_token。 - 由于这个过程涉及多个步骤,原作者提到了参考
outlook-mail-automation项目。简化的流程如下:- 访问一个特定格式的URL,登录你的微软账号并授权。
- 授权成功后,浏览器会跳转到一个你指定的本地地址(如
http://localhost:8080),并在URL参数中附带code。 - 编写一个简单的脚本或使用工具,用这个
code、你的client_id和client_secret(需要在Azure应用里生成)去请求Token端点,返回的JSON中就会包含refresh_token。这个refresh_token是长期有效的(除非撤销授权),脚本将用它来获取短期的access_token以调用邮件API。
-
配置
config.txt:- 在项目根目录创建
config.txt文件。 - 填入以下关键信息(格式示例):
# Microsoft Graph API 配置 client_id = your_azure_app_client_id_here refresh_token = your_long_lived_refresh_token_here tenant_id = common # 或者你的租户ID,个人账户通常用`common`或`consumers` # ChatGPT 账号 (谨慎!建议只在安全环境使用或考虑替代方案) chatgpt_username = your_email@example.com chatgpt_password = your_password_here # 保活脚本配置 keep_alive_interval_minutes = 5 cursor_process_name = Cursor.exe # Windows示例
- 在项目根目录创建
实操心得 :获取
refresh_token这一步是最繁琐的,但一劳永逸。务必妥善保管你的client_secret和refresh_token,它们等同于你的邮箱密码。一个安全实践是不要将密码明文写在config.txt里,而是通过环境变量传入脚本,或者在脚本中读取加密的配置。对于ChatGPT密码,更推荐使用环境变量,并在脚本中使用os.getenv('CHATGPT_PASSWORD')来获取。
4. 核心脚本原理与改造要点
4.1 gpt-accesstoken.py :深入登录与Token提取
这个脚本的进化体现了自动化程度的提升。早期版本可能需要手动处理登录和验证码,而集成 cursor_auth_manager.py 逻辑后,实现了更高程度的自动化。
核心步骤拆解:
- 初始化会话与加载配置 :使用
requests.Session()保持Cookie,读取config.txt中的账号信息。 - 获取登录页面与CSRF Token :请求ChatGPT登录页,从HTML中解析出隐藏的CSRF Token,这是提交登录表单所必需的。
- 提交登录凭证 :向登录接口发送POST请求,包含邮箱、密码和CSRF Token。
- 处理双因素认证(2FA)或验证码 :这是最复杂的部分。如果账号开启了2FA,脚本需要等待用户输入(或从备用渠道获取)TOTP代码。更常见的是邮箱验证码。
- 邮箱验证码自动化 :此时
mail_api.py登场。脚本在提交登录后,如果检测到需要邮箱验证,会: a. 调用mail_api.py模块,使用配置好的client_id和refresh_token,获取微软Graph API的访问令牌。 b. 查询指定邮箱收件箱,过滤出发件人为no-reply@openai.com且主题包含“验证码”的最新邮件。 c. 使用正则表达式从邮件正文中提取出数字验证码。 d. 将验证码自动填入登录流程的下一步表单并提交。
- 邮箱验证码自动化 :此时
- 捕获Access Token :登录完全成功后,ChatGPT网页会跳转,并在某个请求的响应头、Cookie或页面JavaScript变量中包含Access Token。脚本需要通过分析网络请求或解析页面内容来精准定位并提取这个Token。它通常是一个以
eyJ开头的长字符串(JWT格式)。 - Token持久化 :将获取到的Token写入一个本地文件(如
access_token.txt)或更新到config.txt中,供保活脚本或其他工具读取。
可能遇到的挑战与应对:
- Cloudflare防护 :ChatGPT登录页可能有Cloudflare的浏览器检查。简单的
requests请求会被拦截。此时可能需要使用selenium配合真实浏览器(如Chrome)来绕过,或者使用能处理Cloudflare的requests变种库(如cloudscraper)。这会大大增加脚本的复杂度和运行时间。 - 登录流程变更 :OpenAI可能会调整登录接口或参数。脚本需要一定的鲁棒性,或者定期维护更新。
- 验证码识别 :除了邮箱验证码,还可能遇到图片验证码。这就需要集成OCR库(如
ddddocr,pytesseract),成功率并非100%。
4.2 cursor_pro_keep_alive.py :无干扰保活机制
保活脚本的目标是在不影响用户正常使用电脑的前提下,默默维持Cursor Pro的“活跃”状态。
几种常见的保活方法:
-
模拟鼠标微动 :
import pyautogui import time def move_mouse_slightly(): # 获取当前鼠标位置 current_x, current_y = pyautogui.position() # 轻微移动一个像素再移回 pyautogui.moveTo(current_x + 1, current_y) time.sleep(0.05) pyautogui.moveTo(current_x, current_y)- 优点 :简单,跨平台。
- 缺点 :肉眼可见的鼠标跳动,可能干扰用户。需要确保Cursor窗口是前台活动窗口吗?如果不是,移动鼠标可能无效。
-
模拟前台按键 :
import pyautogui # 发送一个无害的按键,如ALT pyautogui.press('alt')- 优点 :比鼠标移动更隐蔽。
- 缺点 :如果焦点在其他输入框,可能会输入字符,造成干扰。需要精确控制目标窗口。
-
Windows API 发送消息 (更优雅):
import win32gui import win32con import time def keep_cursor_alive_win(process_name="Cursor.exe"): # 查找Cursor窗口句柄(这里简化处理,实际可能需要枚举所有窗口) def callback(hwnd, extra): if win32gui.IsWindowVisible(hwnd) and process_name in win32gui.GetWindowText(hwnd): extra.append(hwnd) return True hwnds = [] win32gui.EnumWindows(callback, hwnds) if hwnds: for hwnd in hwnds: # 发送一个无害的系统消息,如WM_NULL (0x0000) win32gui.SendMessage(hwnd, win32con.WM_NULL, 0, 0) # 或者模拟一个键盘消息(更安全) # win32gui.PostMessage(hwnd, win32con.WM_KEYDOWN, win32con.VK_F24, 0) # F24是几乎不用的键 # time.sleep(0.01) # win32gui.PostMessage(hwnd, win32con.WM_KEYUP, win32con.VK_F24, 0) return True return False- 优点 :完全后台操作,对用户零干扰。效率高。
- 缺点 :仅限Windows平台,且需要准确找到目标窗口句柄。
我的实现建议 :优先采用 方法3(发送系统消息) ,因为它最隐蔽、最专业。保活脚本应作为一个后台服务(Windows可用 pythonw.exe 运行,或注册为系统服务;Linux/macOS可用 systemd 或 launchd )持续运行,每隔几分钟(如5分钟)执行一次保活操作。同时,脚本应具备简单的日志功能,记录每次保活操作的时间,便于排查问题。
5. 自动化部署与运维实践
5.1 脚本整合与调度
理想情况下,我们希望两个脚本协同工作:Token获取脚本定期运行(例如每天一次)以更新Token,保活脚本持续运行以维持状态。我们可以创建一个主调度脚本 main_scheduler.py 。
# main_scheduler.py 示例
import schedule
import time
import subprocess
import logging
from datetime import datetime
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
def job_get_token():
logging.info("开始执行Token获取任务...")
try:
# 运行token获取脚本
result = subprocess.run(['python', 'gpt-accesstoken.py'], capture_output=True, text=True, timeout=120)
if result.returncode == 0:
logging.info("Token获取成功")
else:
logging.error(f"Token获取失败: {result.stderr}")
except subprocess.TimeoutExpired:
logging.error("Token获取任务超时")
except Exception as e:
logging.error(f"执行Token获取任务时发生未知错误: {e}")
def job_keep_alive():
# 保活脚本本身应是常驻进程,这里可以设计为检查保活进程是否存在,不存在则启动
pass
if __name__ == '__main__':
# 每天凌晨3点获取一次Token(假设此时网络较空闲)
schedule.every().day.at("03:00").do(job_get_token)
# 立即运行一次Token获取
job_get_token()
logging.info("调度器已启动。")
while True:
schedule.run_pending()
time.sleep(60) # 每分钟检查一次任务
对于保活脚本,更适合作为独立的守护进程启动,而不是由调度器频繁启停。
5.2 系统服务化(以Windows为例)
为了让脚本在开机后自动运行且在后台无界面运行,可以将其注册为Windows服务。
-
使用
pywin32创建服务 :- 编写一个符合Windows服务规范的Python脚本。
- 使用
win32serviceutil.ServiceFramework作为基类。 - 在
SvcDoRun方法中启动你的保活脚本主循环。
-
使用NSSM(推荐给非Python开发者) :
- NSSM是一个将任意命令行程序封装成Windows服务的工具。
- 下载NSSM,在命令行中运行:
nssm install CursorKeepAliveService - 在弹出窗口中设置:
- Path:
C:\Path\To\Your\venv\Scripts\pythonw.exe(使用pythonw避免出现控制台窗口) - Arguments:
C:\Path\To\Your\Project\cursor_pro_keep_alive.py - Startup directory:
C:\Path\To\Your\Project
- Path:
- 在“Log on”标签页,可以设置服务用哪个用户账户运行(确保该账户有必要的权限)。
- 点击“Install service”。之后就可以在“服务”管理器中启动、停止该服务,并设置为开机自启。
5.3 日志与监控
健全的日志系统是运维的基石。两个核心脚本都应输出详细的日志。
# 在每个脚本开头配置日志
import logging
import os
from logging.handlers import RotatingFileHandler
log_dir = "logs"
os.makedirs(log_dir, exist_ok=True)
log_file = os.path.join(log_dir, "cursor_auto.log")
handler = RotatingFileHandler(log_file, maxBytes=5*1024*1024, backupCount=3) # 5MB per file, keep 3 backups
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
logger.addHandler(handler)
# 也可以同时输出到控制台
console_handler = logging.StreamHandler()
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)
logger.info("脚本启动...")
定期检查日志文件,可以快速发现是Token获取失败,还是保活动作未生效。
6. 常见问题排查与进阶优化
6.1 问题排查清单
| 问题现象 | 可能原因 | 排查步骤 |
|---|---|---|
| Token获取脚本报错,无法登录 | 1. 网络问题(代理设置) 2. ChatGPT登录页面改版 3. 账号被风控或需要额外验证 4. 邮箱验证码获取失败 |
1. 检查脚本中的网络请求,确认是否需配置代理( requests 的 proxies 参数)。 2. 手动登录ChatGPT网页,观察流程是否有变。 3. 检查账号是否正常,尝试手动登录。 4. 检查 mail_api.py 的 client_id 和 refresh_token 是否正确,权限是否已授予。手动调用Graph API看能否读到邮件。 |
| Token获取成功,但Cursor Pro仍提示未登录/Token过期 | 1. Token未正确传递给Cursor 2. Token格式错误或已失效 3. Cursor客户端缓存了旧的无效Token |
1. 确认Token被正确写入 config.txt 或目标文件,且保活脚本读取的是同一个文件。 2. 检查获取的Token是否完整(通常以 eyJ 开头)。可以尝试用这个Token直接调用OpenAI API(如 https://api.openai.com/v1/models )验证其有效性。 3. 尝试完全退出Cursor Pro并重新启动,强制其重新读取Token。 |
| 保活脚本运行,但Cursor仍会休眠 | 1. 保活动作未正确作用于Cursor窗口 2. 保活间隔时间太长 3. Cursor Pro版本更新,机制变化 |
1. 检查保活脚本的日志,确认它成功找到了Cursor窗口并执行了操作。尝试换一种保活方式(如从发送消息改为模拟按键)。 2. 缩短 keep_alive_interval_minutes ,例如从5分钟改为3分钟。 3. 观察新版本Cursor的行为,可能需要调整保活策略。 |
| 脚本消耗过高CPU/内存 | 1. 循环检查过于频繁 2. selenium 浏览器实例未正确关闭 3. 内存泄漏 |
1. 增加保活和调度检查的时间间隔。 2. 确保 gpt-accesstoken.py 在使用 selenium 后,无论成功与否都调用 driver.quit() 。 3. 使用 psutil 等工具监控脚本资源占用,优化代码逻辑。 |
6.2 安全与隐私强化建议
- 敏感信息脱敏 :绝对不要将
config.txt提交到Git。使用.gitignore文件将其忽略。更佳实践是使用环境变量或单独的、受权限保护的配置文件(如config.ini)。 - 使用应用密码 :如果ChatGPT账号支持,不要使用主密码,而是生成一个专用的“应用密码”用于脚本登录。这样即使密码泄露,风险也相对可控。
- Token最小化使用 :获取到的Access Token权限很高。确保只在本地使用,不要上传到任何不信任的服务器。
- 定期审计 :定期检查Azure应用的使用情况,以及ChatGPT账号的登录设备列表,确保没有异常活动。
6.3 进阶优化方向
- Token有效性预检 :在保活脚本中,可以增加一个环节:定期(如每小时)用当前Token调用一个简单的OpenAI API(如列出模型)。如果返回401未授权错误,则自动触发
gpt-accesstoken.py重新获取Token,实现完全无人值守。 - 多账号轮换 :如果需要管理多个ChatGPT账号,可以扩展
config.txt,支持配置多个账号的凭证。脚本可以按顺序或根据一定策略(如某个账号Token失效)自动切换账号,并将新Token更新给Cursor。 - 容器化部署 :使用Docker将整个环境(Python、脚本、依赖)打包。可以避免环境差异问题,也便于在服务器或NAS上部署,实现7x24小时运行。
- 开发GUI控制面板 :对于不熟悉命令行的用户,可以开发一个简单的图形界面,用于启动/停止服务、查看日志、手动触发Token刷新等,提升易用性。
这套自动化方案的核心思想,是将一个手动、易中断的过程,通过本地脚本串联起来,形成一个稳定的自治系统。它需要一定的初始配置和调试成本,但一旦跑通,就能为你换来持久、流畅的Cursor Pro使用体验。在构建过程中,你也会对网络请求、桌面自动化、API集成有更深入的理解。记住,自动化是为了提升效率,但在涉及账号安全的操作上,务必谨慎,做好隔离和监控。
更多推荐



所有评论(0)