避免gspread脚本崩溃:API配额与连接问题解决方案问询
解决方案:gspread长时脚本的错误处理与请求控制
针对你遇到的两类长时脚本特有的问题,推荐用带重试+速率控制的装饰器来统一处理,既解决代码冗余问题,又能优雅应对配额超限和连接错误。
一、实现通用装饰器
这个装饰器会自动处理429配额超限和ConnectionResetError,同时内置速率控制,替代你手动调用的api_requests_timer():
import time import functools from gspread.exceptions import APIError def gspread_safe_operation(max_retries=5, base_delay=1, max_delay=10, request_interval=1.2): def decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): retries = 0 while retries < max_retries: try: # 控制请求间隔,避免触发配额限制 time.sleep(request_interval) return func(*args, **kwargs) except APIError as e: if e.response.status_code == 429: # 优先遵循API返回的Retry-After头 retry_after = e.response.headers.get("Retry-After") delay = int(retry_after) if retry_after else base_delay * (2 ** retries) delay = min(delay, max_delay) print(f"429配额超限,等待{delay}秒后重试...") time.sleep(delay) retries += 1 else: # 其他API错误直接抛出 raise except ConnectionResetError: print("连接被重置,1秒后重试...") time.sleep(1) retries += 1 # 重试次数耗尽后抛出异常 raise Exception(f"已重试{max_retries}次,仍无法完成操作") return wrapper return decorator
二、装饰器使用示例
把需要调用gspread API的函数用这个装饰器标记即可,不用再写重复的try-except和计时逻辑:
import gspread from oauth2client.service_account import ServiceAccountCredentials # 初始化gspread客户端(你的原有代码) scope = ["https://spreadsheets.google.com/feeds", "https://www.googleapis.com/auth/drive"] creds = ServiceAccountCredentials.from_json_keyfile_name("your-creds.json", scope) client = gspread.authorize(creds) sheet = client.open("你的表格").sheet1 # 用装饰器包装操作函数 @gspread_safe_operation(max_retries=5, request_interval=1.5) def update_cell(row, col, value): sheet.update_cell(row, col, value) @gspread_safe_operation(max_retries=5) def get_range_data(range_str): return sheet.get(range_str) # 长时任务逻辑(你的原有代码) for i in range(1000): update_cell(i+1, 1, f"数据{i+1}") data = get_range_data(f"A{i+1}:B{i+1}") # 其他业务逻辑...
三、额外优化建议
批量操作减少请求数:尽量用
batch_update()替代多次单个单元格更新,比如:@gspread_safe_operation() def batch_update_cells(cells): sheet.batch_update(cells)这能从根源上降低触发429的概率。
缓存重复读取的数据:如果脚本中需要多次读取相同范围的数据,用字典缓存结果,避免重复请求。
调整参数适配你的场景:根据Google Sheets API的配额(默认每100秒100次请求),调整
request_interval参数;如果网络不稳定,可提高max_retries次数。
内容的提问来源于stack exchange,提问作者Michał Szajer
相关产品推荐
相关产品推荐

