python 下载文件的几种方式分享


Posted in Python onApril 07, 2021

1 、一般同步下载

示例代码:

import requests
import os

def downlaod(url, file_path):
  headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Firefox/68.0"
  }
  r = requests.get(url=url, headers=headers)
  with open(file_path, "wb") as f:
    f.write(r.content)
    f.flush()

2、 使用流式请求,requests.get方法的stream

默认情况下是stream的值为false,它会立即开始下载文件并存放到内存当中,倘若文件过大就会导致内存不足的情况,程序就会报错。
当把get函数的stream参数设置成True时,它不会立即开始下载,当你使用iter_content或iter_lines遍历内容或访问内容属性时才开始下载,需要注意一点:文件没有下载之前,它也需要保持连接。

iter_content:一块一块的遍历要下载的内容
iter_lines:一行一行的遍历要下载的内容

使用上面两个函数下载大文件可以防止占用过多的内存,因为每次只下载小部分数据。

示例代码:

3 、异步下载文件

由于request的请求是阻塞式的,所以要用aiohttp模块来发起请求。

示例代码:

import aiohttp
import asyncio
import os


async def handler(url, file_path):
  headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Firefox/68.0"
  }
  async with aiohttp.ClientSession() as session:
    r = await session.get(url=url, headers=headers)
    with open(file_path, "wb") as f:
      f.write(await r.read())
      f.flush()
      os.fsync(f.fileno())


loop = asyncio.get_event_loop()
loop.run_until_complete(handler(url, file_path))

4、 异步拆分下载文件

上面用的是一个协程下载一个文件,下面的方法是将文件分成几部分,每个部分用一个协程下载,最后再写入文件。

下面这个例子用的是流式写入,即把内容写入到磁盘里面。

import aiohttp
import asyncio
import time
import os


async def consumer(queue):
  option = await queue.get()
  start = option["start"]
  end = option["end"]
  url = option["url"]
  filename = option["filename"]
  i = option["i"]

  print(f"第{i}个任务开始运行")
  async with aiohttp.ClientSession() as session:
    headers = {"Range": f"bytes={start}-{end}"}
    r = await session.get(url=url, headers=headers)
    with open(filename, "rb+") as f:
      f.seek(start)
      while True:
        chunk = await r.content.read(end - start)
        if not chunk:
          break
        f.write(chunk)
        f.flush()
        os.fsync(f.fileno())
        print(f"第{i}个任务正在写入中ing")
    queue.task_done()
    print(f"第{i}个任务写入成功")


async def producer(url, headers, filename, queue, coro_num):
  async with aiohttp.ClientSession() as session:
    resp = await session.head(url=url, headers=headers)
    file_size = int(resp.headers["content-length"])
    # 创建一个文件
    with open(filename, "wb") as f:
      pass
    part = file_size // coro_num
    for i in range(coro_num):
      start = part * i
      if i == coro_num - 1:
        end = file_size
      else:
        end = start + part
      info = {
        "start": start,
        "end": end,
        "url": url,
        "filename": filename,
        "i": i,
      }
      queue.put_nowait(info)


async def main():
  # 需要填的有url,filename,coro_num
  url = ""
  filename = ""
  coro_num = 0
  headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Firefox/68.0"
  }
  queue = asyncio.Queue(coro_num)
  await producer(url, headers, filename, queue, coro_num)
  task_list = []
  for i in range(coro_num):
    task = asyncio.create_task(consumer(queue))
    task_list.append(task)
  await queue.join()
  for i in task_list:
    i.cancel()
  await asyncio.gather(*task_list)


startt = time.time()
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
end = time.time() - startt
print(f"用了{end}秒")

5、注意

以上的示例都是介绍思路,程序并不健壮,健壮的程序需要加入错误捕获和错误处理。

以上就是python 下载文件的几种方式分享的详细内容,更多关于python 下载文件的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
从零学Python之入门(四)运算
May 27 Python
Python中使用摄像头实现简单的延时摄影技术
Mar 27 Python
使用Python编写类UNIX系统的命令行工具的教程
Apr 15 Python
解析Python中的异常处理
Apr 28 Python
python使用matplotlib绘制柱状图教程
Feb 08 Python
利用python将图片转换成excel文档格式
Dec 30 Python
微信跳一跳小游戏python脚本
Jan 05 Python
python处理csv数据动态显示曲线实例代码
Jan 23 Python
详解django三种文件下载方式
Apr 06 Python
python提取具有某种特定字符串的行数据方法
Dec 11 Python
django2.2 和 PyMySQL版本兼容问题
Feb 17 Python
python GUI库图形界面开发之PyQt5信号与槽的高级使用技巧(自定义信号与槽)详解与实例
Mar 06 Python
完美处理python与anaconda环境变量的冲突问题
python 如何用map()函数创建多线程任务
python requests模块的使用示例
Apr 07 #Python
Python 使用dict实现switch的操作
Apr 07 #Python
Python 把两层列表展开平铺成一层(5种实现方式)
Apr 07 #Python
Python获取百度热搜的完整代码
详解Python小数据池和代码块缓存机制
Apr 07 #Python
You might like
DC的38部超级英雄动画电影
2020/03/03 欧美动漫
在PHP中输出JS语句以及乱码问题的解决方案
2019/02/13 PHP
Laravel 解决419错误 -ajax请求错误的问题(CSRF验证)
2019/10/25 PHP
基于jQuery的投票系统显示结果插件
2011/08/12 Javascript
利用a标签自动解析URL分析网址实例
2014/10/20 Javascript
关于编写性能高效的javascript事件的技术
2014/11/28 Javascript
js实现的简洁网页滑动tab菜单效果代码
2015/08/24 Javascript
bootstrap fileinput 插件使用项目总结(经验)
2017/02/22 Javascript
微信小程序左右滑动的实现代码
2017/12/15 Javascript
详解JavaScript的BUG和错误
2018/05/07 Javascript
Vue导出页面为PDF格式的实现思路
2018/07/31 Javascript
详解Vue结合后台的列表增删改案例
2018/08/21 Javascript
原生JS实现旋转轮播图+文字内容切换效果【附源码】
2018/09/29 Javascript
vue elementUI table表格数据 滚动懒加载的实现方法
2019/04/04 Javascript
vue 实现滚动到底部翻页效果(pc端)
2019/07/31 Javascript
详解json串反转义(消除反斜杠)
2019/08/12 Javascript
layui监听单元格编辑前后交互的例子
2019/09/16 Javascript
[02:36]DOTA2亚洲邀请赛小组赛精彩集锦:EE凭借法力虚空拿下4杀
2017/03/30 DOTA
python抓取京东价格分析京东商品价格走势
2014/01/09 Python
Python循环语句之break与continue的用法
2015/10/14 Python
使用python实现语音文件的特征提取方法
2019/01/09 Python
Pytorch之parameters的使用
2019/12/31 Python
Python selenium抓取虎牙短视频代码实例
2020/03/02 Python
python函数中将变量名转换成字符串实例
2020/05/11 Python
Python API 操作Hadoop hdfs详解
2020/06/06 Python
keras中epoch,batch,loss,val_loss用法说明
2020/07/02 Python
运行Python编写的程序方法实例
2020/10/21 Python
CSS3 优势以及网页设计师如何使用CSS3技术
2009/07/29 HTML / CSS
贝玲妃美国官方网站:Benefit美国
2016/08/28 全球购物
大整数数相乘的问题
2012/07/22 面试题
什么是反射
2012/03/17 面试题
龙潭大峡谷导游词
2015/02/10 职场文书
幼儿园园长工作总结2015
2015/05/25 职场文书
pyqt5打包成exe可执行文件的方法
2021/05/14 Python
JAVA SpringMVC实现自定义拦截器
2022/03/16 Python
2021年国产动漫公司排行前十名,玄机科技上榜,第二推出过铠甲勇士
2022/03/18 杂记