Python如何从指定URL下载文件 无需预先知晓文件名及文件类型
用Python从URL下载文件(无需预先知晓文件名和类型)
实现思路
完全模拟浏览器的下载逻辑,核心处理浏览器默认执行的几个操作:
- 自动跟进所有重定向,拿到最终的资源地址
- 优先从响应头的
Content-Disposition字段提取官方指定的文件名 - 若响应头未提供文件名,则从最终资源URL的路径末尾提取文件名
- 采用流模式下载,适配任意大小的文件,不会占用过多内存
前置依赖
需要先安装第三方HTTP库requests:
pip install requests
完整可运行代码
import os import re import cgi import requests from urllib.parse import unquote def download_from_url(url: str, save_dir: str = "./") -> str: # 模拟浏览器请求头,避免被站点拦截 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" } # 发起请求,允许重定向,开启流下载模式 resp = requests.get(url, headers=headers, allow_redirects=True, stream=True, timeout=30) resp.raise_for_status() # 请求失败直接抛出异常 # 第一步:从响应头提取文件名 filename = "" content_disposition = resp.headers.get("Content-Disposition") if content_disposition: _, params = cgi.parse_header(content_disposition) if "filename" in params: filename = params["filename"] # 处理URL编码的文件名 if "%" in filename: filename = unquote(filename) # 第二步:响应头没拿到文件名就从最终URL的路径提取 if not filename: final_url_path = unquote(resp.url.split("?")[0]) filename = final_url_path.rstrip("/").split("/")[-1] # 处理文件名中的非法字符(适配Windows、macOS、Linux系统) filename = re.sub(r'[\\/*?:"<>|]', "_", filename) # 确保保存目录存在 os.makedirs(save_dir, exist_ok=True) save_full_path = os.path.join(save_dir, filename) # 流写入文件 with open(save_full_path, "wb") as f: for chunk in resp.iter_content(chunk_size=8192): if chunk: f.write(chunk) return save_full_path # 测试调用 if __name__ == "__main__": test_url = "https://sourceforge.net/projects/portableapps/files/PortableApps.com%20Platform/PortableApps.com_Platform_Setup_19.0.paf.exe/download?use_mirror=deac-fra&use_mirror=deac-fra&r=" saved_path = download_from_url(test_url) print(f"文件已保存到:{saved_path}")
关键逻辑说明
- 请求头模拟:添加了和桌面Chrome一致的User-Agent,避免大部分站点的反爬拦截
- 文件名提取:完全对齐浏览器的文件名识别逻辑,优先用站点指定的文件名, fallback到URL路径提取
- 流下载:每次只加载8KB的数据到内存,就算是几个G的大文件也能正常下载
- 非法字符处理:自动替换文件名中各个系统不允许的字符,避免保存失败
内容的提问来源于stack exchange,提问作者mimasik
相关产品推荐
相关产品推荐

