从Google Sheet读取URL并遍历爬取数据的问题排查与实现
问题分析与解决方案
核心问题点
- URL格式错误:
freshurls.get_all_records()返回的是字典组成的列表(每个字典对应一行数据,键为表头字段),而非直接的URL字符串。循环中把字典传给requests.get()会直接触发错误,但被空except捕获后无任何提示,导致无输出。 - 错误处理无效:导入的
skip是unittest的测试跳过装饰器,在此处完全无用;空except会掩盖所有异常(网络错误、JSON解析错误、Sheet权限问题等),无法定位问题根源。 - 重复操作Sheet:同时用
gc.open_by_key和gc.open("NBA Stories")打开同一Sheet,属于冗余操作,可能引发权限或同步问题。
修正后的代码
import requests from bs4 import BeautifulSoup as bs import json import gspread # 初始化Google Sheet连接(仅执行一次) gc = gspread.service_account(filename='creds.json') sh = gc.open_by_key('1NFrhsJT7T0zm3dRaP5J8OY0FryBHy5W_wEEGvwBg58I') # 定义读写工作表 output_worksheet = sh.sheet1 # 写入爬取结果的工作表 url_worksheet = sh.get_worksheet(1) # 存储待爬URL的工作表(索引从0开始) headers = { 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.79 Safari/537.36' } # 读取URL列数据(假设URL在第一列,跳过表头) urls = url_worksheet.col_values(1) if urls: urls = urls[1:] # 移除表头行 for url in urls: url = url.strip() if not url: continue # 跳过空行 try: # 发送请求并检查状态 r = requests.get(url, headers=headers) r.raise_for_status() # 解析页面 soup = bs(r.text, 'html.parser') page_obj = soup.select_one('script#__NEXT_DATA__') if not page_obj: print(f"未找到目标数据脚本:{url}") continue json_obj = json.loads(page_obj.text) # 安全解析JSON字段,避免KeyError story = json_obj.get('props', {}).get('pageProps', {}).get('story', {}) title = story.get('header', {}).get('headline', '无标题') date = story.get('date', '无日期') content = str(story.get('content', '无内容')) # 写入Sheet output_worksheet.append_row([url, title, date, content]) print(f"成功处理:{url}") except Exception as e: print(f"处理URL {url} 失败:{str(e)}") continue
关键改进说明
- 正确读取URL:
- 用
col_values(1)直接提取第一列的URL数据,若存在表头则跳过第一行; - 若Sheet带表头(如表头为"URL"),也可通过字典提取:
records = url_worksheet.get_all_records() urls = [record.get('URL') for record in records if record.get('URL')]
- 用
- 完善错误处理:
- 替换空
except为except Exception as e,打印具体错误信息便于排查; - 增加
r.raise_for_status()检查HTTP请求是否成功(如404、500错误); - 用
get()方法逐层解析JSON,避免因字段缺失触发KeyError。
- 替换空
- 优化Sheet操作:
- 仅初始化一次Sheet连接,通过同一对象获取不同工作表,减少冗余操作;
- 跳过空URL,避免无效请求。
- 调试与进度跟踪:添加状态打印,实时了解爬取进度和异常情况。
额外注意事项
- 确保服务账号权限:将
creds.json中client_email字段的邮箱添加为Sheet的编辑者; - 控制请求频率:添加
time.sleep(2)等延迟,避免被NBA官网封禁IP; - 批量写入优化:若爬取数据量大,可收集多条数据后用
append_rows批量写入,提升效率。
内容的提问来源于stack exchange,提问作者Anthony Madle
相关产品推荐
相关产品推荐

