news 2026/5/10 3:38:54

Python如何下载文件:从基础到进阶的完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python如何下载文件:从基础到进阶的完整指南

在Python中下载文件是一项常见任务,无论是从网页下载图片、文档,还是通过API获取数据,掌握文件下载技术都是开发者的必备技能。本文将系统介绍Python下载文件的多种方法,涵盖基础实现、高级技巧和常见问题解决方案。


一、基础方法:使用标准库下载文件

1. 使用urllib.request(Python内置库)

importurllib.request url="https://example.com/file.zip"filename="downloaded_file.zip"try:urllib.request.urlretrieve(url,filename)print(f"文件已下载到:{filename}")exceptExceptionase:print(f"下载失败:{e}")

特点

  • 无需安装第三方库
  • 适合简单下载场景
  • 缺乏进度显示和错误处理细节

2. 使用requests库(推荐)

importrequests url="https://example.com/file.zip"filename="downloaded_file.zip"try:response=requests.get(url,stream=True)# 使用流式下载大文件response.raise_for_status()# 检查请求是否成功withopen(filename,'wb')asf:forchunkinresponse.iter_content(chunk_size=8192):# 分块写入ifchunk:# 过滤掉keep-alive新块f.write(chunk)print(f"文件已下载到:{filename}")exceptrequests.exceptions.RequestExceptionase:print(f"下载失败:{e}")

优势

  • 更简洁的API
  • 支持流式下载(适合大文件)
  • 完善的错误处理机制
  • 可添加请求头、代理等高级功能

二、进阶技巧:增强下载功能

1. 显示下载进度

importrequestsfromtqdmimporttqdm# 需要安装: pip install tqdmurl="https://example.com/large_file.zip"filename="large_file.zip"try:response=requests.get(url,stream=True)total_size=int(response.headers.get('content-length',0))withopen(filename,'wb')asf,tqdm(desc=filename,total=total_size,unit='iB',unit_scale=True,unit_divisor=1024,)asbar:forchunkinresponse.iter_content(chunk_size=8192):f.write(chunk)bar.update(len(chunk))print("\n下载完成!")exceptExceptionase:print(f"下载失败:{e}")

2. 断点续传功能

importosimportrequests url="https://example.com/large_file.zip"filename="large_file.zip"# 检查是否已部分下载downloaded_size=0ifos.path.exists(filename):downloaded_size=os.path.getsize(filename)headers={'Range':f'bytes={downloaded_size}-'}try:response=requests.get(url,headers=headers,stream=True)response.raise_for_status()withopen(filename,'ab')asf:# 以追加模式打开forchunkinresponse.iter_content(chunk_size=8192):ifchunk:f.write(chunk)print("下载完成!")exceptExceptionase:print(f"下载失败:{e}")

3. 多线程/异步下载(加速下载)

importrequestsfromconcurrent.futuresimportThreadPoolExecutorimportosdefdownload_chunk(url,start,end,filename,chunk_num):headers={'Range':f'bytes={start}-{end}'}try:response=requests.get(url,headers=headers,stream=True)withopen(f"{filename}.part{chunk_num}",'wb')asf:forchunkinresponse.iter_content(chunk_size=8192):f.write(chunk)returnTrueexceptExceptionase:print(f"分块{chunk_num}下载失败:{e}")returnFalsedefmerge_files(filename,num_chunks):withopen(filename,'wb')asoutfile:foriinrange(num_chunks):part_filename=f"{filename}.part{i}"ifos.path.exists(part_filename):withopen(part_filename,'rb')asinfile:outfile.write(infile.read())os.remove(part_filename)url="https://example.com/very_large_file.zip"filename="very_large_file.zip"file_size=1024*1024*100# 假设文件100MBchunk_size=1024*1024*10# 每块10MBnum_chunks=file_size//chunk_size# 创建线程池下载各分块withThreadPoolExecutor(max_workers=5)asexecutor:futures=[]foriinrange(num_chunks):start=i*chunk_size end=start+chunk_size-1ifi!=num_chunks-1elsefile_size-1futures.append(executor.submit(download_chunk,url,start,end,filename,i))# 等待所有分块下载完成forfutureinfutures:future.result()# 合并分块merge_files(filename,num_chunks)print("下载并合并完成!")

三、常见场景解决方案

1. 下载网页上的所有资源

importrequestsfrombs4importBeautifulSoupimportosdefdownload_resources(url,output_folder="downloads"):os.makedirs(output_folder,exist_ok=True)try:response=requests.get(url)soup=BeautifulSoup(response.text,'html.parser')# 下载图片forimginsoup.find_all('img'):img_url=img.get('src')ifimg_urlandnotimg_url.startswith('data:'):ifnotimg_url.startswith(('http://','https://')):img_url=f"{url}/{img_url}"ifnoturl.endswith('/')elsef"{url}{img_url}"try:img_data=requests.get(img_url).content img_name=os.path.join(output_folder,img_url.split('/')[-1])withopen(img_name,'wb')asf:f.write(img_data)exceptExceptionase:print(f"图片下载失败:{e}")# 可以类似地下载CSS/JS等资源print("资源下载完成!")exceptExceptionase:print(f"网页下载失败:{e}")download_resources("https://example.com")

2. 使用代理下载

importrequests proxies={'http':'http://10.10.1.10:3128','https':'http://10.10.1.10:1080',}url="https://example.com"try:response=requests.get(url,proxies=proxies)withopen("page.html",'w',encoding='utf-8')asf:f.write(response.text)print("通过代理下载成功!")exceptExceptionase:print(f"代理下载失败:{e}")

3. 处理下载重定向

importrequests url="http://example.com/redirecting_link"try:response=requests.get(url,allow_redirects=True)# 默认允许重定向final_url=response.url# 获取最终URLprint(f"最终URL:{final_url}")# 下载最终文件withopen("final_file.txt",'wb')asf:f.write(response.content)exceptExceptionase:print(f"下载失败:{e}")

四、最佳实践与注意事项

  1. 错误处理:始终添加异常处理,特别是网络请求可能因各种原因失败
  2. 资源清理:使用with语句确保文件正确关闭
  3. 大文件处理:使用流式下载(stream=True)和分块写入
  4. 安全性
    • 验证SSL证书(默认行为)
    • 对用户提供的URL进行验证
    • 限制文件类型和保存路径
  5. 性能优化
    • 合理设置分块大小(通常8KB-1MB)
    • 多线程下载适合高延迟网络
    • 考虑使用异步IO(如aiohttp)提高并发性能

五、完整示例:带进度条的下载函数

importrequestsfromtqdmimporttqdmimportosdefdownload_file(url,filename=None,chunk_size=8192):""" 下载文件并显示进度条 :param url: 文件URL :param filename: 保存文件名(可选,默认从URL提取) :param chunk_size: 分块大小(字节) :return: 保存的文件路径 """try:# 获取文件名(如果未提供)iffilenameisNone:filename=os.path.basename(url.split('?')[0])# 去除查询参数# 发送请求response=requests.get(url,stream=True)response.raise_for_status()# 获取总大小(如果服务器提供)total_size=int(response.headers.get('content-length',0))# 创建进度条progress_bar=tqdm(desc=filename,total=total_size,unit='iB',unit_scale=True,unit_divisor=1024,)# 写入文件withopen(filename,'wb')asf:forchunkinresponse.iter_content(chunk_size=chunk_size):f.write(chunk)progress_bar.update(len(chunk))progress_bar.close()print(f"\n文件已保存到:{os.path.abspath(filename)}")returnfilenameexceptrequests.exceptions.RequestExceptionase:print(f"下载失败:{e}")returnNone# 使用示例download_file("https://example.com/sample.pdf","my_document.pdf")

总结

Python提供了多种下载文件的方法,从简单的urllib到功能强大的requests库,再到结合多线程/异步的优化方案。根据实际需求选择合适的方法:

  • 简单下载:requests.get()+ 文件写入
  • 大文件下载:流式下载 + 分块写入
  • 需要进度显示:结合tqdm
  • 高并发需求:多线程/异步下载
  • 特殊需求:代理、断点续传等高级功能

掌握这些技术后,你可以轻松应对各种文件下载场景,构建更健壮的Python应用程序。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/10 3:38:53

PCIe验证挑战与MVC解决方案解析

1. PCIe验证的挑战与MVC解决方案PCI Express(PCIe)作为现代计算系统中关键的高速串行总线标准,其协议栈的复杂性给验证工作带来了巨大挑战。一个典型的PCIe 3.0设备需要处理的事务类型超过50种,物理层状态机包含20多个状态转换路径…

作者头像 李华
网站建设 2026/5/10 3:38:48

AI驱动的联盟营销自动化:52个技能构建数据闭环飞轮

1. 项目概述:用AI技能构建你的自动化联盟营销飞轮如果你正在做联盟营销,或者想通过内容创作变现,那你一定经历过这些痛苦:花几个小时搜索“最好的联盟项目”,结果全是SEO垃圾文章;凭感觉写内容,…

作者头像 李华
网站建设 2026/5/10 3:37:39

AI应用后端架构实战:从模型集成到生产部署的最佳实践

1. 项目概述与核心价值最近在GitHub上看到一个名为“umutbasal/ai”的项目,第一眼看到这个仓库名,很多人可能会觉得它又是一个大而全的AI框架或者工具集。但点进去仔细研究后,我发现它的定位非常有意思:它不是一个试图解决所有问题…

作者头像 李华
网站建设 2026/5/10 3:35:46

linux安装 jdk-7u25-linux-x64.tar.gz 详细步骤(解压配置环境变量)

在技术领域,我们常常被那些闪耀的、可见的成果所吸引。今天,这个焦点无疑是大语言模型技术。它们的流畅对话、惊人的创造力,让我们得以一窥未来的轮廓。然而,作为在企业一线构建、部署和维护复杂系统的实践者,我们深知…

作者头像 李华
网站建设 2026/5/10 3:34:36

CANN/HCCL执行超时配置

HCCL_EXEC_TIMEOUT 【免费下载链接】hccl 集合通信库(Huawei Collective Communication Library,简称HCCL)是基于昇腾AI处理器的高性能集合通信库,为计算集群提供高性能、高可靠的通信方案 项目地址: https://gitcode.com/cann/…

作者头像 李华
网站建设 2026/5/10 3:32:40

APC:统一管理AI编程工具配置,告别配置孤岛与同步困境

1. 项目概述:告别AI工具配置孤岛 如果你和我一样,日常开发中同时用着Claude Code、Cursor、GitHub Copilot,可能还会在终端里调戏一下Gemini CLI,那你一定深有体会:每个工具都是一个信息孤岛。我在Claude Code里精心调…

作者头像 李华