爬取GOGOV站点新冠疫苗数据触发HTTP Error 503的解决方案咨询
解决方案
- 修改请求头伪装浏览器
pandas内置的read_html方法默认使用的请求头特征非常容易被反爬策略识别,建议改用requests库发起请求,手动添加浏览器真实UA和其他请求头后,再将返回的页面内容传给read_html解析:
import requests import pandas as pd # 配置模拟浏览器的请求头 headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "ru-RU,ru;q=0.9,en;q=0.8" } def save(source, name, directory, region_code = None): # 先手动发起请求 resp = requests.get(source, headers=headers, timeout=15) resp.raise_for_status() # 用请求返回的内容解析表格 ru_region_save = pd.read_html(resp.content, header=0)[0] if region_code is not None: ru_region_save['region_code'] = region_code ru_region_save.to_csv(directory + name, index=False)
- 添加随机请求间隔
连续高频请求是触发反爬的核心原因之一,每次调用save方法后随机等待3-10秒,模拟真实用户的浏览节奏:
import time import random # 假设你循环遍历data_list_region爬取每个区域数据,在调用save前后加延迟 for region_info in data_list_region: # 构造你的请求链接、文件名等参数 save(...) # 随机等待 time.sleep(random.randint(3,10))
- 增加错误重试机制
遇到503报错时不要直接终止程序,设置3次重试,每次重试前等待10-20秒,大概率可以恢复正常请求:
def save(source, name, directory, region_code = None, max_retry=3): for retry_idx in range(max_retry): try: resp = requests.get(source, headers=headers, timeout=15) resp.raise_for_status() break except Exception as e: if retry_idx == max_retry - 1: raise e print(f"请求失败,{15 * (retry_idx + 1)}秒后重试") time.sleep(15 * (retry_idx + 1)) ru_region_save = pd.read_html(resp.content, header=0)[0] if region_code is not None: ru_region_save['region_code'] = region_code ru_region_save.to_csv(directory + name, index=False)
- 可选优化:复用Cookie、使用代理
如果以上方案仍触发验证码,可以将首次请求拿到的Cookie存储下来,后续所有请求都携带该Cookie;如果爬取量较大,可以搭配代理IP池,每次请求更换IP规避封禁。
内容的提问来源于stack exchange,提问作者kostya ivanov
相关产品推荐
相关产品推荐

