You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Python从Google Sheets单元格提取批注?

解决Google Sheets提取单元格批注并结合gspread、pandas的问题

要提取Google Sheets单元格的批注,gspread和pygsheets确实没有直接封装这个功能,但可以直接调用Google Sheets API的原生接口来实现,再和你已有的数据处理流程结合。

核心思路

通过Google Sheets API的spreadsheets.get方法,请求时指定includeGridData=True,就能获取包含单元格批注的详细数据,之后将批注和gspread拿到的行数据对应合并。

修改后的完整代码

import json
import pandas as pd
from google.oauth2 import service_account
from googleapiclient.discovery import build
import gspread

# 加载服务账号凭证
with open("automate-0738852.json", 'r') as j:
    service_account_info = json.loads(j.read())

# 必须添加spreadsheets权限才能读取批注
scope = [
    'https://spreadsheets.google.com/feeds',
    'https://www.googleapis.com/auth/drive',
    'https://www.googleapis.com/auth/spreadsheets'
]
creds_with_scope = service_account.Credentials.from_service_account_info(service_account_info, scopes=scope)

# 初始化gspread客户端(用于获取行数据)
client = gspread.authorize(creds_with_scope)
spreadsheet = client.open_by_url('https://docs.google.com/spreadsheets/d/spreadsheetID/edit?usp=sharing')
worksheet = spreadsheet.get_worksheet(0)

# 获取表格数据(保留你原来的逻辑)
records_data = worksheet.get_all_records(head=6)
records_df = pd.DataFrame.from_dict(records_data)
records_df.columns = records_df.columns.astype(str).str.strip()
records_df.drop(columns=[''], errors='ignore', inplace=True)

# 初始化Sheets API服务(用于获取批注)
sheets_service = build('sheets', 'v4', credentials=creds_with_scope)
spreadsheet_id = spreadsheet.id
worksheet_title = worksheet.title

# 请求包含批注的表格数据,指定要获取的工作表范围
response = sheets_service.spreadsheets().get(
    spreadsheetId=spreadsheet_id,
    ranges=[worksheet_title],
    includeGridData=True
).execute()

# 解析批注:建立单元格位置到批注的映射
cell_notes = {}
worksheet_data = response['sheets'][0]['data'][0]
for row_idx, row in enumerate(worksheet_data['rowData']):
    if 'values' not in row:
        continue
    for col_idx, cell in enumerate(row['values']):
        if 'note' in cell:
            # 转换为A1格式(比如第7行第1列是A7)
            col_letter = gspread.utils.rowcol_to_a1(1, col_idx+1)[0]
            cell_address = f"{col_letter}{row_idx+1}"
            cell_notes[cell_address] = cell['note']

# 将批注合并到DataFrame中:假设每行对应表格中从第7行开始(因为head=6)
# 给DataFrame新增一列存储该行各单元格的批注字典
records_df['cell_notes'] = None
for df_row_idx, (_, df_row) in enumerate(records_df.iterrows()):
    sheet_row_num = 7 + df_row_idx  # 表头是第6行,数据从第7行开始
    row_notes = {}
    for df_col_idx, col_name in enumerate(records_df.columns):
        col_letter = gspread.utils.rowcol_to_a1(1, df_col_idx+1)[0]
        cell_address = f"{col_letter}{sheet_row_num}"
        if cell_address in cell_notes:
            row_notes[col_name] = cell_notes[cell_address]
    records_df.at[df_row_idx, 'cell_notes'] = row_notes

# 输出结果示例
print(records_df.head())

关键说明

  1. 权限范围:新增https://www.googleapis.com/auth/spreadsheets是读取批注的必要权限,否则API会返回权限不足的错误。
  2. 批注解析逻辑:通过遍历API返回的rowData,提取每个单元格的note字段,并用A1格式的单元格地址作为键存储。
  3. 数据对应:因为你用了head=6,所以实际数据行从表格的第7行开始,需要把DataFrame的行索引和表格的行号对应起来,才能正确匹配批注。
  4. 合并方式:示例中给DataFrame新增了cell_notes列,存储每行各字段对应的批注字典,你可以根据需求调整成其他格式(比如单独的列存储对应字段的批注)。

内容的提问来源于stack exchange,提问作者veerg404

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 00:27:29