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

使用requests.get()批量爬取NHL数据遇401错误的优化方案咨询

问题

使用requests.get()爬取多个不同URL的NHL赛事数据,小样本测试时能正常获取数据(响应码200),但通过gameIds循环批量请求时,若列表过大最终会出现401响应码。希望在不降低运行效率的前提下解决该问题。

相关代码:

gameIds=['2022020022','2022020028','2022020044','2022020072','2022020088'] #can be much larger list

#function to get data from web
def get_data(gameId): 
   url=f'https://api-web.nhle.com/v1'
   proxies={}
   verify=''
   headers={}
   response=requests.get(url + f'/gamecenter/{gameId}/play-by-play')
   
   if response.status_code == 200:
      data=response.json()
      return data

   else:
      print('status code <> 200, status code is ' + str(response.status_code))

all_data=[] #empty list to append each game's data
for i in gameIds:
   data=get_data(i)
   all_data.append(data)

注:已在requests.get()中添加proxies、headers、verify参数,但因隐私无法公开。确认代码在小样本下可行,需排查401错误的原因及解决办法。

401错误原因分析

  • 请求频率过高触发反爬:NHL的API对批量请求有速率限制,小样本请求量低未触发阈值,大列表循环快速请求会被服务器判定为恶意爬取,部分API会用401(未授权)替代429(请求过多)作为限流响应。
  • 会话/身份验证信息失效:批量请求过程中,headers中的验证信息(如token、Cookie)过期或被服务器重置,导致后续请求失去权限。
  • 代理IP被封禁:若使用代理,批量请求中单个IP的请求次数过多,被服务器识别并封禁,引发无权限响应。

高效解决办法(不降低运行效率)

1. 添加随机化请求延迟

避免固定间隔的机械请求,用0.5-1.5秒的随机等待平衡速率控制和运行效率,既规避限流,又不会过度拖慢任务。

2. 使用requests.Session保持会话

复用TCP连接和会话状态,减少重复建立连接的开销,同时维持验证信息的有效性,降低被服务器识别为异常请求的概率。

3. 代理池轮换(若使用代理)

准备多个可用代理IP,每次请求随机切换代理,避免单个IP因请求量过大被封禁,保证批量请求的连续性。

4. 内置重试机制

遇到401错误时自动重试,同时刷新会话或切换代理,避免临时失效导致整个任务中断。

优化后的示例代码:

import requests
import random
import time

gameIds=['2022020022','2022020028','2022020044','2022020072','2022020088']

# 初始化会话,复用连接和验证信息
session = requests.Session()
session.proxies = {}  # 替换为你的代理配置
session.headers = {}  # 替换为你的headers信息
session.verify = ''   # 替换为你的verify设置

def get_data(gameId): 
    url = f'https://api-web.nhle.com/v1/gamecenter/{gameId}/play-by-play'
    retry_count = 2  # 设置重试次数
    for _ in range(retry_count):
        try:
            response = session.get(url)
            if response.status_code == 200:
                return response.json()
            elif response.status_code == 401:
                # 401时刷新会话,重新设置验证信息
                global session
                session = requests.Session()
                session.proxies = {}  # 重新配置代理
                session.headers = {}  # 重新配置headers
                session.verify = ''
                print(f"请求{gameId}出现401,正在重试...")
                continue
            else:
                print(f"请求{gameId}失败,状态码:{response.status_code}")
                return None
        except Exception as e:
            print(f"请求{gameId}发生异常:{str(e)}")
            return None
    print(f"请求{gameId}重试{retry_count}次仍失败")
    return None

all_data = []
for game_id in gameIds:
    data = get_data(game_id)
    all_data.append(data)
    # 添加随机延迟,避免触发限流
    time.sleep(random.uniform(0.5, 1.5))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 13:22:05