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 25 Python
深入理解Python中的元类(metaclass)
Feb 14 Python
详解Python中最难理解的点-装饰器
Apr 03 Python
Python建立Map写Excel表实例解析
Jan 17 Python
python模拟登陆,用session维持回话的实例
Dec 27 Python
Django框架封装外部函数示例
May 28 Python
python:动态路由的Flask程序代码
Nov 22 Python
浅谈tensorflow使用张量时的一些注意点tf.concat,tf.reshape,tf.stack
Jun 23 Python
Python函数递归调用实现原理实例解析
Aug 11 Python
python+selenium 简易地疫情信息自动打卡签到功能的实现代码
Aug 22 Python
用pip给python安装matplotlib库的详细教程
Feb 24 Python
pytorch 梯度NAN异常值的解决方案
Jun 05 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
apache配置虚拟主机的方法详解
2013/06/17 PHP
CI框架学习笔记(二) -入口文件index.php
2014/10/27 PHP
php操作(删除,提取,增加)zip文件方法详解
2015/03/12 PHP
PC端微信扫码支付成功之后自动跳转php版代码
2017/07/07 PHP
js操作select控件的几种方法
2010/06/02 Javascript
Javascript中的delete介绍
2012/09/02 Javascript
JavaScript的递归之递归与循环示例介绍
2013/08/05 Javascript
js函数模拟显示桌面.scf程序示例
2014/04/20 Javascript
三种动态加载js的jquery实例代码另附去除js方法
2014/04/30 Javascript
js使用removeChild方法动态删除div元素
2014/08/01 Javascript
JS使用post提交的两种方式
2015/12/03 Javascript
html5+javascript实现简单上传的注意细节
2016/04/18 Javascript
深入解析Backbone.js框架的依赖库Underscore.js的作用
2016/05/07 Javascript
jquery中取消和绑定hover事件的实现代码
2016/06/02 Javascript
详解React 16 中的异常处理
2017/07/28 Javascript
nodejs调取微信收货地址的方法
2017/12/20 NodeJs
webpack4.0 入门实践教程
2018/10/08 Javascript
如何在Vue中使用CleaveJS格式化你的输入内容
2018/12/14 Javascript
浅谈Express.js解析Post数据类型的正确姿势
2019/05/30 Javascript
node获取客户端ip功能简单示例
2019/08/24 Javascript
js实现点赞按钮功能的实例代码
2020/03/06 Javascript
Vue 解决在element中使用$notify在提示信息中换行问题
2020/11/11 Javascript
Python的词法分析与语法分析
2013/05/18 Python
编写Python脚本使得web页面上的代码高亮显示
2015/04/24 Python
用tensorflow构建线性回归模型的示例代码
2018/03/05 Python
使用sklearn对多分类的每个类别进行指标评价操作
2020/06/11 Python
python Gabor滤波器讲解
2020/10/26 Python
美国卡车、吉普车和SUV零件网站:4 Wheel Parts
2016/11/24 全球购物
新加坡网上美容店:Hermo新加坡
2019/06/19 全球购物
万代美国官网:PREMIUM BANDAI USA
2020/09/11 全球购物
2014年村支部书记四风对照检查材料思想汇报
2014/10/02 职场文书
教师批评与自我批评总结
2014/10/16 职场文书
文明旅游倡议书
2015/04/28 职场文书
狂人日记读书笔记
2015/06/30 职场文书
2016年小学端午节活动总结
2016/04/01 职场文书
浅谈哪个Python库才最适合做数据可视化
2021/06/28 Python