如何通过GCal API用Python批量导出谷歌日历至文件并定时执行?
解决Google Calendar多日历批量导出的Python方案
嘿,我来帮你搞定这个需求!Google Calendar API确实没有提供直接「一键导出到文件」的接口,但完全可以通过API拉取每个日历的所有事件数据,再手动写入独立文件——这个操作其实比你想象的简单,而且完全能满足你每日自动运行的需求。
核心思路
Google Calendar API的设计是让你主动获取数据,然后自己处理存储。所以我们的流程是:
- 获取你名下所有日历的列表(拿到每个日历的唯一ID)
- 遍历每个日历,拉取它的所有事件数据(处理分页,因为事件多的话一次拉不完)
- 将每个日历的事件数据保存为独立文件(JSON/CSV都可以,看你需求)
- 用crontab配置每日自动运行脚本
具体实现步骤
1. 前期准备
- 先在Google Cloud控制台启用Calendar API,创建OAuth 2.0客户端凭证(因为是导出个人日历,OAuth比服务账号更方便,不需要额外共享日历权限),下载
credentials.json到脚本目录。 - 安装依赖包:
pip install google-api-python-client google-auth-httplib2 google-auth-oauthlib
2. Python脚本示例
下面是完整的脚本,实现了拉取所有日历并导出为JSON文件:
import os import json from google.auth.transport.requests import Request from google.oauth2.credentials import Credentials from google_auth_oauthlib.flow import InstalledAppFlow from googleapiclient.discovery import build from googleapiclient.errors import HttpError # 权限范围,只需要读取日历数据就行 SCOPES = ['https://www.googleapis.com/auth/calendar.readonly'] def get_calendar_service(): creds = None # 之前授权过的话会保存token.json,后续自动加载 if os.path.exists('token.json'): creds = Credentials.from_authorized_user_file('token.json', SCOPES) # 如果没有有效凭证,重新授权 if not creds or not creds.valid: if creds and creds.expired and creds.refresh_token: creds.refresh(Request()) else: flow = InstalledAppFlow.from_client_secrets_file( 'credentials.json', SCOPES) creds = flow.run_local_server(port=0) # 保存凭证供下次使用 with open('token.json', 'w') as token: token.write(creds.to_json()) return build('calendar', 'v3', credentials=creds) def export_all_calendars(): try: service = get_calendar_service() # 1. 获取所有日历列表 calendars_result = service.calendarList().list().execute() calendars = calendars_result.get('items', []) if not calendars: print("没找到任何日历!") return # 2. 遍历每个日历,拉取所有事件 for calendar in calendars: calendar_id = calendar['id'] calendar_name = calendar['summary'].replace('/', '_').replace('\\', '_') # 处理文件名非法字符 print(f"正在导出日历:{calendar_name}") events = [] page_token = None # 分页拉取所有事件,直到没有下一页 while True: events_result = service.events().list( calendarId=calendar_id, pageToken=page_token, singleEvents=True, # 展开重复事件的所有实例,不需要的话可以设为False orderBy='startTime' ).execute() events.extend(events_result.get('items', [])) page_token = events_result.get('nextPageToken') if not page_token: break # 3. 保存为JSON文件 output_file = f"{calendar_name}_events.json" with open(output_file, 'w', encoding='utf-8') as f: json.dump(events, f, ensure_ascii=False, indent=2) print(f"已导出到文件:{output_file}") except HttpError as error: print(f"API请求出错:{error}") if __name__ == '__main__': export_all_calendars()
3. 关键细节说明
- 重复事件处理:脚本里设置了
singleEvents=True,会把重复事件(比如每周例会)的所有实例都拉取出来;如果只需要主事件,把这个参数改成False就行。 - 文件名处理:把日历名称里的
/和\替换成下划线,避免生成非法文件名。 - API配额:Google Calendar API的每日配额是10000次请求,8个日历每个拉取几次分页请求,完全不会超配额,放心用。
4. Crontab配置(每日自动运行)
假设你的脚本路径是/home/yourname/gcal_export.py,Python路径是/usr/bin/python3,想要每天凌晨2点运行:
- 打开crontab编辑:
crontab -e - 添加一行:
这样脚本会每天凌晨2点运行,输出日志到0 2 * * * /usr/bin/python3 /home/yourname/gcal_export.py >> /home/yourname/gcal_export.log 2>&1gcal_export.log,方便排查问题。
常见问题排查
- 如果第一次运行脚本弹出授权页面,正常完成授权就行,后续会自动用
token.json登录。 - 如果遇到权限错误,检查你的OAuth凭证是否正确,以及日历是否设置为可访问(个人日历默认都是自己可访问的)。
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

