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中self原理实例分析
Apr 30 Python
详解Python 数据库 (sqlite3)应用
Dec 07 Python
python 计算数组中每个数字出现多少次--“Bucket”桶的思想
Dec 19 Python
使用pycharm生成代码模板的实例
May 23 Python
对python csv模块配置分隔符和引用符详解
Dec 12 Python
Python list列表中删除多个重复元素操作示例
Feb 27 Python
正则给header的冒号两边参数添加单引号(Python请求用)
Aug 09 Python
Python猴子补丁Monkey Patch用法实例解析
Mar 23 Python
python3发送request请求及查看返回结果实例
Apr 30 Python
在django中实现choices字段获取对应字段值
Jul 12 Python
如何理解及使用Python闭包
Jun 01 Python
python解析照片拍摄时间进行图片整理
Jul 23 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
《魔兽争霸3:重制版》翻车了?你想要的我们都没有
2019/11/07 魔兽争霸
PHP 日期时间函数的高级应用技巧
2009/10/10 PHP
php快速查找数据库中恶意代码的方法
2015/04/01 PHP
PHP5.3新特性小结
2016/02/14 PHP
php实现算术验证码功能
2018/12/05 PHP
php设计模式之状态模式实例分析【星际争霸游戏案例】
2020/03/26 PHP
Laravel登录失败次数限制的实现方法
2020/08/26 PHP
几个比较经典常用的jQuery小技巧
2010/03/01 Javascript
编写针对IE的JS代码两种编写方法
2013/01/30 Javascript
IE 下Enter提交表单存在重复提交问题的解决方法
2014/05/04 Javascript
jQuery实现点击小图显示大图代码分享
2015/08/25 Javascript
JavaScript判断表单为空及获取焦点的方法
2016/02/12 Javascript
利用css+原生js制作简单的钟表
2020/04/07 Javascript
JS去除重复并统计数量的实现方法
2016/12/15 Javascript
基于AngularJS的拖拽文件上传的实例代码
2017/07/15 Javascript
详解angularjs实现echart图表效果最简洁教程
2017/11/29 Javascript
[36:19]2018DOTA2亚洲邀请赛 小组赛 A组加赛 Newbee vs LGD
2018/04/03 DOTA
python中的lambda表达式用法详解
2016/06/22 Python
Android分包MultiDex策略详解
2017/10/30 Python
Python编程之基于概率论的分类方法:朴素贝叶斯
2017/11/11 Python
关于django 数据库迁移(migrate)应该知道的一些事
2018/05/27 Python
浅析python中的迭代与迭代对象
2018/10/08 Python
python实现KNN分类算法
2019/10/16 Python
Pytorch对Himmelblau函数的优化详解
2020/02/29 Python
安装多个版本的TensorFlow的方法步骤
2020/04/21 Python
Keras中的多分类损失函数用法categorical_crossentropy
2020/06/11 Python
python excel多行合并的方法
2020/12/09 Python
澳洲国民品牌乡村路折扣店:Country Road & Trenery Outlet
2018/04/19 全球购物
Lentiamo荷兰:在线订购隐形眼镜、隐形眼镜液和太阳镜
2019/10/25 全球购物
金士达面试非笔试
2012/03/14 面试题
UML设计模式笔试题
2014/06/07 面试题
求职自荐信的格式
2014/04/07 职场文书
2014年清明节网上祭英烈寄语
2014/04/09 职场文书
电话客服工作职责
2014/07/27 职场文书
功夫熊猫观后感
2015/06/10 职场文书
一篇文章带你了解Python和Java的正则表达式对比
2021/09/15 Python