使用urllib从网站下载文件时遭遇403 Forbidden错误求助
解决urllib下载BLS文件返回403 Forbidden错误的方案
问题根源
服务器拒绝请求并非因为需要身份认证,而是默认的urllib请求携带的User-Agent是Python专属标识,被网站的反爬/安全策略拦截了。
修复代码
给请求添加模拟浏览器的User-Agent头部,同时优化路径处理逻辑,避免潜在问题:
import os import urllib.request files = [ 'sm/sm.data.1.AllData', 'ce/ce.data.0.AllCESSeries', ] # 安全拼接路径,兼容不同操作系统 dir_path = os.path.abspath(os.path.dirname(__file__)) datadir = os.path.join(dir_path, "data") # 确保data目录存在,避免因目录缺失报错 os.makedirs(datadir, exist_ok=True) os.chdir(datadir) data_hostname = "http://download.bls.gov/pub/time.series/" current_filesystem = datadir def download_data(): # 模拟Chrome浏览器的User-Agent,替换成你常用浏览器的标识也可以 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36' } for filename in files: filename_extension = filename[3:] + ".txt" data_location = data_hostname + filename full_filepath = os.path.join(current_filesystem, filename_extension) print(f"downloading from: {data_location}") # 创建携带自定义头部的请求 req = urllib.request.Request(data_location, headers=headers) try: # 读取响应并写入本地文件 with urllib.request.urlopen(req) as response, open(full_filepath, 'wb') as out_file: out_file.write(response.read()) except urllib.error.URLError as e: print(f"下载失败: {str(e.reason)}") continue print(f"download path: {full_filepath}") urllib.request.urlcleanup() print("Finished Downloading Data") # 执行下载 download_data()
关键改动说明
- 添加自定义User-Agent:让服务器识别请求来自常规浏览器,绕过拦截
- 替换urlretrieve为Request+urlopen:
urlretrieve无法直接添加请求头部,改用更灵活的请求方式 - 使用os.path.join处理路径:避免手动拼接路径导致的跨系统兼容问题
- 确保目录存在:新增
os.makedirs确保数据目录存在,防止下载时因目录缺失报错 - 异常捕获:添加错误处理,方便定位具体失败原因
额外提示
- 如果仍出现403,可以尝试更换其他浏览器的User-Agent字符串
- 若批量下载多个文件,建议添加
time.sleep(1)之类的延时,避免请求过于频繁触发限制
内容的提问来源于stack exchange,提问作者kushagra kartik
相关产品推荐
相关产品推荐

