Google Forms JSON数据是否缺失分段Item ID?如何提取跳转逻辑?
Google Forms API分段Item ID缺失问题与跳转逻辑提取方案
问题描述
通过Google Forms API拉取的JSON数据中,跳转逻辑字段goToSectionId指向目标分段头的Item ID,但返回数据中似乎找不到该ID对应的分段头或关联问题;questionId作为问题的Item ID,与分段ID不匹配,goToSectionId的值仅出现一次无对应映射,导致无法正常提取跳转逻辑。
Python拉取Google Form数据的代码如下:
from __future__ import print_function from apiclient import discovery from httplib2 import Http from oauth2client.service_account import ServiceAccountCredentials import json SCOPES = "https://www.googleapis.com/auth/forms.body.readonly" DISCOVERY_DOC = "https://forms.googleapis.com/$discovery/rest?version=v1" def get_google_form_data(form_id): creds = ServiceAccountCredentials.from_json_keyfile_name('service.json', SCOPES) http_auth = creds.authorize(Http()) service = discovery.build('forms', 'v1', http=http_auth, discoveryServiceUrl=DISCOVERY_DOC, static_discovery=False) result = service.forms().get(formId=form_id).execute() return result if __name__ == "__main__": form_id = 'xxx' json_data = get_google_form_data(form_id) with open("form_data.json", "w") as f: json.dump(json_data, f, indent=4)
核心原因与API说明
Google Forms中,分段(Section)在API返回数据里是以SECTION_HEADER类型的Item存在的,每个分段头都有唯一的itemId,这个ID就是跳转逻辑中goToSectionId对应的目标值。之前找不到映射是因为未筛选出SECTION_HEADER类型的条目。
解决方案
1. 提取分段与ID的映射
遍历API返回的items数组,筛选出type为"SECTION_HEADER"的条目,这些就是分段头,其itemId即为分段的唯一标识。同时可以关联分段下的所有问题(从当前分段头开始,到下一个分段头或数组结束的所有非分段头Item)。
2. 解析跳转逻辑
跳转逻辑中的goToSectionId直接对应分段头的itemId;若该值为"0",则代表跳转到问卷末尾(结束答题)。
完整处理代码
在原有拉取代码基础上,添加分段和跳转逻辑解析的函数:
from __future__ import print_function from apiclient import discovery from httplib2 import Http from oauth2client.service_account import ServiceAccountCredentials import json SCOPES = "https://www.googleapis.com/auth/forms.body.readonly" DISCOVERY_DOC = "https://forms.googleapis.com/$discovery/rest?version=v1" def get_google_form_data(form_id): creds = ServiceAccountCredentials.from_json_keyfile_name('service.json', SCOPES) http_auth = creds.authorize(Http()) service = discovery.build('forms', 'v1', http=http_auth, discoveryServiceUrl=DISCOVERY_DOC, static_discovery=False) result = service.forms().get(formId=form_id).execute() return result def parse_section_and_jump_logic(form_data): # 构建分段ID与分段信息、下属问题的映射 section_map = {} current_section_id = None for item in form_data.get('items', []): item_id = item.get('itemId') # 识别分段头 if item.get('type') == 'SECTION_HEADER': current_section_id = item_id section_title = item.get('sectionHeader', {}).get('title', f"未命名分段 {len(section_map)+1}") section_map[current_section_id] = { 'title': section_title, 'questions': [] } # 将问题归入当前分段 elif current_section_id and item.get('type') == 'QUESTION': section_map[current_section_id]['questions'].append({ 'question_id': item_id, 'title': item.get('questionItem', {}).get('question', {}).get('title') }) # 提取所有带跳转逻辑的问题详情 jump_logic_list = [] for item in form_data.get('items', []): if item.get('type') == 'QUESTION': question_item = item.get('questionItem', {}).get('question', {}) go_to_id = question_item.get('goToSectionId') if go_to_id: # 处理跳转目标:分段或结束问卷 target = section_map.get(go_to_id, {}).get('title', '结束问卷') if go_to_id != '0' else '结束问卷' jump_logic_list.append({ 'question_id': item.get('itemId'), 'question_title': question_item.get('title'), 'go_to_section_id': go_to_id, 'target': target }) return section_map, jump_logic_list if __name__ == "__main__": form_id = 'xxx' json_data = get_google_form_data(form_id) with open("form_data.json", "w") as f: json.dump(json_data, f, indent=4) # 解析并打印分段与跳转逻辑 sections, jump_logics = parse_section_and_jump_logic(json_data) print("=== 表单分段信息 ===") print(json.dumps(sections, indent=4, ensure_ascii=False)) print("\n=== 跳转逻辑详情 ===") print(json.dumps(jump_logics, indent=4, ensure_ascii=False))
注意事项
- 确保使用的ServiceAccountCredentials拥有
forms.body.readonly权限,否则无法获取完整的表单结构数据。 goToSectionId为"0"是系统特殊值,对应问卷结束,而非具体分段。
内容的提问来源于stack exchange,提问作者Hack-R
相关产品推荐
相关产品推荐

