使用Python结合Google Drive API v3读取文件修订内容到Pandas DataFrame
解决Google Drive API读取修订版内容到Pandas DataFrame的问题
问题分析
你遇到的核心问题分两点:
- 调用
revisions().get_media()时触发HttpError:大概率是因为文件类型(如Google原生文档)不支持直接用get_media,或者权限不足、修订版已被系统清理 - 调用
revisions().get()只能拿到元数据:这是该接口的设计逻辑,get方法仅返回修订版的元信息,不包含文件内容
另外你的修订历史获取代码存在bug:while循环中每次都会覆盖revisions变量,导致最终只返回最后一页的修订记录,需要改为extend追加。
解决方案
根据文件类型分两种处理方式,核心思路是通过API获取修订版的文件流,再用Pandas解析成DataFrame:
1. 修正修订历史获取代码
import io import pandas as pd from google_apis import create_service from googleapiclient.http import MediaIoBaseDownload from googleapiclient.errors import HttpError CLIENT_FILE = 'client_secret.json' API_NAME = 'drive' API_VERSION = 'v3' SCOPES = ['https://www.googleapis.com/auth/drive'] service = create_service(CLIENT_FILE, API_NAME, API_VERSION, SCOPES) def get_file_revision_history(file_id): response = service.revisions().list( fileId=file_id, fields='*', pageSize=1000 ).execute() revisions = response.get('revisions', []) nextPageToken = response.get('nextPageToken') while nextPageToken: response = service.revisions().list( fileId=file_id, fields='*', pageSize=1000, pageToken=nextPageToken ).execute() # 修正:用extend追加,而非覆盖 revisions.extend(response.get('revisions', [])) nextPageToken = response.get('nextPageToken') return revisions file_id = '1E8Wbd80CbFlFSHYZQkApXMM9EQOz1lQRl4m3rfq-vdY' revision_history = get_file_revision_history(file_id)
2. 读取修订版内容到DataFrame
情况A:上传的非原生文件(如CSV、Excel、TXT)
这类文件可以直接通过get_media获取流,再用Pandas解析:
def read_revision_to_df(file_id, revision_id): try: # 创建内存流存储文件内容 file_stream = io.BytesIO() request = service.revisions().get_media(fileId=file_id, revisionId=revision_id) downloader = MediaIoBaseDownload(file_stream, request) done = False while done is False: status, done = downloader.next_chunk() # 重置流指针到开头 file_stream.seek(0) # 根据文件类型选择解析方式,这里以CSV为例 df = pd.read_csv(file_stream) # 如果是Excel:df = pd.read_excel(file_stream) return df except HttpError as e: print(f"读取修订版失败:{e}") return None # 调用示例 revision_id = '104' revision_df = read_revision_to_df(file_id, revision_id) if revision_df is not None: print(revision_df.head())
情况B:Google原生文件(如Google Sheets、Docs)
原生文件无法直接用get_media,需要调用export接口导出为可解析的格式(如CSV):
def export_google_revision_to_df(file_id, revision_id): try: # 针对Google Sheets,导出为CSV格式;其他类型可替换MIME类型 # Google Docs可导出为text/plain,Google Slides暂时无法导出为表格格式 mime_type = 'text/csv' request = service.revisions().export_media( fileId=file_id, revisionId=revision_id, mimeType=mime_type ) file_stream = io.BytesIO() downloader = MediaIoBaseDownload(file_stream, request) done = False while done is False: status, done = downloader.next_chunk() file_stream.seek(0) df = pd.read_csv(file_stream) return df except HttpError as e: print(f"导出修订版失败:{e}") return None # 调用示例 revision_df = export_google_revision_to_df(file_id, revision_id) if revision_df is not None: print(revision_df.head())
关键注意事项
- 权限:确保你的OAuth2 scope包含
https://www.googleapis.com/auth/drive(已在代码中设置),否则无法访问私有文件的修订版 - 修订版可用性:部分旧修订版可能被Google Drive自动清理,调用前可通过
revisions().get()检查published字段是否为True - MIME类型对应:不同文件类型需要匹配正确的导出MIME类型,比如Google Sheets的CSV对应
text/csv,Excel对应application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
内容的提问来源于stack exchange,提问作者Muyukani Kizito
相关产品推荐
相关产品推荐

