Python3下载hesa.ac.uk的CSV文件遇403错误及方案咨询
解决Python3从HESA网站下载CSV时的403错误及Jupyter Notebook下载方法
问题分析
你遇到的403 Forbidden错误是因为HESA网站的反爬机制识别出了默认的Python请求头(这类请求头很容易被判定为非浏览器请求),直接拒绝了你的访问。另外你代码里有个小细节问题:print(print(full_link))会额外输出None,因为print()函数本身没有返回值,改成print(full_link)就能解决这个小问题。
解决方案
推荐使用更简洁易用的requests库处理下载,或者使用urllib的现代API避免弃用警告,两种方法都需要添加模拟浏览器的请求头。
方法1:使用requests库(推荐)
requests库处理HTTP请求更直观,代码可读性更高。如果你的环境还没安装,先在Jupyter里运行安装命令:
!pip install requests
然后使用以下代码下载文件:
import requests # 待下载的CSV链接列表 csv_links = ['/data-and-analysis/finances/table-2.csv', '/data-and-analysis/finances/table-3.csv', '/data-and-analysis/finances/table-3s.csv', '/data-and-analysis/finances/table-4.csv', '/data-and-analysis/finances/table-9.csv', '/data-and-analysis/finances/table-10.csv'] # 模拟浏览器的请求头,核心是User-Agent字段 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' } base_url = 'https://www.hesa.ac.uk' for link in csv_links: full_url = base_url + link print(f"正在下载: {full_url}") # 发送带请求头的GET请求 response = requests.get(full_url, headers=headers) response.raise_for_status() # 如果请求失败,直接抛出异常提示 # 提取文件名并保存到当前目录 filename = link.split('/')[-1] with open(filename, 'wb') as f: f.write(response.content) print(f"{filename} 下载完成\n")
方法2:使用urllib的现代API(避免弃用警告)
如果你不想额外安装库,可以使用urllib.request的Request对象添加请求头,替代已弃用的FancyURLopener:
import urllib.request csv_links = ['/data-and-analysis/finances/table-2.csv', '/data-and-analysis/finances/table-3.csv', '/data-and-analysis/finances/table-3s.csv', '/data-and-analysis/finances/table-4.csv', '/data-and-analysis/finances/table-9.csv', '/data-and-analysis/finances/table-10.csv'] headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' } base_url = 'https://www.hesa.ac.uk' for link in csv_links: full_url = base_url + link print(f"正在下载: {full_url}") # 创建带请求头的Request对象 req = urllib.request.Request(full_url, headers=headers) with urllib.request.urlopen(req) as response: # 读取响应内容并保存文件 filename = link.split('/')[-1] with open(filename, 'wb') as f: f.write(response.read()) print(f"{filename} 下载完成\n")
Jupyter Notebook中的注意事项
- 下载的文件会保存在Jupyter的当前工作目录中,你可以用以下命令查看当前路径:
# Linux/macOS !pwd # Windows !cd - 如果需要指定自定义保存路径,直接修改
open(filename, 'wb')中的filename为完整路径即可,比如'/home/user/hesa_data/table-2.csv'。
内容的提问来源于stack exchange,提问作者The smell of roses
相关产品推荐
相关产品推荐

