Python从URL下载3GB gz文件返回index.html的解决方法
问题根因
你下载到index.html的核心原因是请求地址错了:https://transparency-in-coverage.uhc.com/是站点前端单页应用的入口,你带的file参数是给前端JS读取用的,JS运行后才会拼接出真实文件地址发起下载请求。requests不会执行页面里的JS代码,直接请求根路径只能拿到前端入口的HTML文件。
修复方案
这个站点的所有披露文件实际存储路径固定为https://transparency-in-coverage.uhc.com/api/v1/uhc/blobs/[文件名],不需要经过前端页面跳转,直接请求该直链即可拿到目标gz文件,同时优化大文件下载的配置:
- 补充常规浏览器请求头,避免被站点反爬策略拦截
- 调大下载块大小,原代码1KB的块会产生大量IO操作,下载3GB文件效率极低,调整为8MB块更合理
- 过滤空chunk,避免写入无效内容
- 增加返回类型校验,第一时间识别异常返回,避免浪费带宽下载无效HTML文件
修正后代码
import requests filename = "2022-07-01_United-HealthCare-Services_Third-Party-Administrator_EP1-50_C1_in-network-rates.json.gz" # 直接拼接真实文件直链 target_url = f"https://transparency-in-coverage.uhc.com/api/v1/uhc/blobs/{filename}" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36" } with requests.get(target_url, stream=True, headers=headers) as r: r.raise_for_status() # 提前校验返回类型,避免再次下到HTML content_type = r.headers.get("Content-Type", "") if "text/html" in content_type: raise ValueError("请求返回了HTML页面,直链规则可能已变动,请在浏览器开发者工具中确认最新文件地址") with open(filename, "wb") as f: for chunk in r.iter_content(chunk_size=8*1024*1024): if chunk: f.write(chunk)
校验提示
- 如果触发类型校验报错,可以在浏览器打开原链接,按F12打开网络面板,筛选
fetch/xhr请求,找到实际发起的gz文件请求,替换target_url即可 - stream模式下载不会把整个3GB文件加载到内存,普通配置的机器也能正常运行
内容的提问来源于stack exchange,提问作者Abhishek Jain
相关产品推荐
相关产品推荐

