Python使用requests无法从特定站点下载文件的问题排查
问题原因及解决办法
原因分析
- 反爬机制拦截:AMD官网服务器会验证请求完整性,你的请求缺少
Referer、Accept等关键请求头,或是旧会话的Cookie已失效,导致服务器判定为非合法请求,拒绝提供文件。 - 大文件内存加载问题:直接用
dl.content会把500+MB文件一次性加载到内存,既容易引发内存溢出,也可能触发服务器流量限制策略,导致下载中断。 - 异常捕获过于宽泛:
except:捕获所有异常,无法定位具体错误(如请求失败、头信息缺失等),不利于排查问题。
解决办法
1. 补充完整请求头
模拟真实浏览器请求头,让服务器识别为合法请求:
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36', 'Referer': 'https://www.amd.com/fr/support/graphics/amd-radeon-6000-series/amd-radeon-6900-series/amd-radeon-rx-6900-xt', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'fr-FR,fr;q=0.8,en-US;q=0.5,en;q=0.3' }
2. 分块下载大文件
用stream=True开启流式下载,逐块写入文件,避免内存压力:
def dl_btn(self): try: # 开启流式下载,避免一次性加载大文件到内存 dl = web.get(self.link, stream=True) dl.raise_for_status() # 主动抛出HTTP错误(如403、404) # 解析文件名,兼容无Content-Disposition的情况 content_disposition = dl.headers.get('Content-Disposition') if content_disposition: file_name = content_disposition.split('=')[1].strip('"') else: file_name = self.link.split('/')[-1] # 选择保存路径 save_dir = filedialog.askdirectory() if not save_dir: return # 用户取消选择路径 file_path = f"{save_dir}/{file_name}" # 分块写入文件 with open(file_path, "wb") as f: for chunk in dl.iter_content(chunk_size=8192): # 每次下载8KB if chunk: f.write(chunk) except requests.exceptions.RequestException as e: print(f"下载错误详情: {e}") # 可根据错误类型做对应处理,比如重新建立会话 # popen(f'start {self.link}')
3. 确保会话有效性
AMD下载链接通常和会话Cookie绑定,旧会话过期后需重新建立有效会话:
# 先访问驱动页面,建立活跃会话 web.get('https://www.amd.com/fr/support/graphics/amd-radeon-6000-series/amd-radeon-6900-series/amd-radeon-rx-6900-xt') # 再获取下载链接并发起下载请求
4. 精准捕获异常
替换宽泛的except:为具体异常类型,比如requests.exceptions.RequestException,能打印出具体错误信息(如403禁止访问、404链接失效),快速定位问题。
内容的提问来源于stack exchange,提问作者user19428688
相关产品推荐
相关产品推荐

