如何通过循环实现Google自定义搜索API获取超10条结果?
Google自定义搜索API多页结果批量导出到CSV
问题
现有一段Python代码,能将Google自定义搜索API返回的JSON数据转换为CSV文件,但该API每页仅返回10条结果。需要修改代码实现自动分页请求:通过循环添加&start=11、&start=21等参数获取下一页数据,当某次返回结果不足10条时停止,所有结果追加到同一个CSV文件中。
原代码如下:
import csv import json import requests url = ('https://www.googleapis.com/customsearch/v1?key=APIKEY&cx=SEARCGENGINEID&q=QUERY&sort=date:r:20231001:20231102') response = requests.get(url) response_dict = response.json() file = open("Testing.csv", "w", newline='') header = ['Site', 'Title', 'URL', 'Author', 'Date'] writer = csv.writer(file) writer.writerow(header) out_rows = 0 for item in response_dict.get('items', []): title = item.get('title', '') url = item.get('link', '') author = item.get('pagemap', {}).get('metatags', [{}])[0].get('author', '') date = item.get('pagemap', {}).get('metatags', [{}])[0].get('article:published_time', '') site = item.get('pagemap', {}).get('metatags',[{}])[0].get('og:site_name','') data = [site, title, url, author, date] writer.writerow(data) out_rows += 1 file.close() print(f"OK! Published file with {out_rows} articles.") with open("Testing.json", "w") as json_file: json.dump(response_dict, json_file, indent=2)
解决方案
最简实现方式是通过循环递增start参数分页请求,控制文件写入模式(首次写入表头,后续追加数据),并根据返回结果数量判断终止时机。修改后的代码如下:
import csv import json import requests # 基础URL模板,预留start参数位置 base_url = 'https://www.googleapis.com/customsearch/v1?key=APIKEY&cx=SEARCGENGINEID&q=QUERY&sort=date:r:20231001:20231102&start={}' out_rows = 0 first_run = True # 标记首次运行,用于写入表头 while True: # 计算当前页的start值:第1页start=1,第2页start=11,以此类推 start = 1 + out_rows url = base_url.format(start) response = requests.get(url) response_dict = response.json() # 处理API错误(如配额耗尽、参数错误) if 'error' in response_dict: print(f"API请求错误: {response_dict['error']['message']}") break items = response_dict.get('items', []) item_count = len(items) # 控制文件模式:首次用写模式,后续用追加模式 with open("Testing.csv", 'w' if first_run else 'a', newline='') as file: writer = csv.writer(file) if first_run: writer.writerow(['Site', 'Title', 'URL', 'Author', 'Date']) first_run = False # 写入当前页数据 for item in items: title = item.get('title', '') url = item.get('link', '') author = item.get('pagemap', {}).get('metatags', [{}])[0].get('author', '') date = item.get('pagemap', {}).get('metatags', [{}])[0].get('article:published_time', '') site = item.get('pagemap', {}).get('metatags', [{}])[0].get('og:site_name', '') writer.writerow([site, title, url, author, date]) out_rows += 1 # 若当前页结果不足10条,说明已到最后一页,终止循环 if item_count < 10: break print(f"OK! Published file with {out_rows} articles.") # 可选:保存最后一次API响应的JSON数据 with open("Testing_last_response.json", "w") as json_file: json.dump(response_dict, json_file, indent=2)
关键改动说明
- 使用URL模板动态生成带
start参数的请求地址,避免手动拼接字符串 - 通过
first_run标记确保CSV表头仅写入一次,后续打开文件使用追加模式(a) - 利用已写入的总行数
out_rows计算下一页的start值,符合API的分页规则 - 增加API错误处理逻辑,避免程序因异常响应崩溃
- 判断当前页返回结果数量,不足10条时自动终止循环
内容的提问来源于stack exchange,提问作者Keir Plaice
相关产品推荐
相关产品推荐

