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通过加号运算符操作列表的方法
Jul 28 Python
Python实现一个简单的验证码程序
Nov 03 Python
Sanic框架蓝图用法实例分析
Jul 17 Python
python进阶之多线程对同一个全局变量的处理方法
Nov 09 Python
python+opencv实现阈值分割
Dec 26 Python
python conda操作方法
Sep 11 Python
Pytorch中的variable, tensor与numpy相互转化的方法
Oct 10 Python
Python tensorflow实现mnist手写数字识别示例【非卷积与卷积实现】
Dec 19 Python
Python内置方法和属性应用:反射和单例(推荐)
Jun 19 Python
增大python字体的方法步骤
Jul 05 Python
Python绘图之二维图与三维图详解
Aug 04 Python
Python操作word文档插入图片和表格的实例演示
Oct 25 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
PHP面向对象的进阶学习(抽像类、接口、final、类常量)
2012/05/07 PHP
Linux下安装PHP MSSQL扩展教程
2014/10/24 PHP
typecho插件编写教程(五):核心代码
2015/05/28 PHP
在第一个input框内输入内容.textarea自动得到第一个文件框的值的javascript代码
2007/04/20 Javascript
js中top的作用深入剖析
2014/03/04 Javascript
创建js对象和js类的方法汇总
2014/12/24 Javascript
深入理解JavaScript单体内置对象
2016/06/06 Javascript
纯JS前端实现分页代码
2016/06/21 Javascript
jQuery基本选择器和层次选择器学习使用
2017/02/27 Javascript
JavaScript表单验证完美代码
2017/03/02 Javascript
jquery实现下拉菜单的手风琴效果
2017/07/23 jQuery
ajax与jsonp的区别及用法
2018/10/16 Javascript
Vuejs通过拖动改变元素宽度实现自适应
2020/09/02 Javascript
Python 深入理解yield
2008/09/06 Python
Python显示进度条的方法
2014/09/20 Python
python3.5 tkinter实现页面跳转
2018/01/30 Python
Python 12306抢火车票脚本
2018/02/07 Python
python如何从文件读取数据及解析
2019/09/19 Python
Python算法的时间复杂度和空间复杂度(实例解析)
2019/11/19 Python
Python+opencv+pyaudio实现带声音屏幕录制
2019/12/23 Python
Cython编译python为so 代码加密示例
2019/12/23 Python
mac在matplotlib中显示中文的操作方法
2020/03/06 Python
使用canvas绘制贝塞尔曲线
2014/12/17 HTML / CSS
html5响应式开发自动计算fontSize的方法
2020/01/13 HTML / CSS
Allen Edmonds官方网站:一家美国优质男士鞋类及配饰制造商
2019/03/12 全球购物
Lululemon加拿大官网:加拿大知名体育服装零售商
2019/04/12 全球购物
Eton丹麦官网:精美的男式衬衫
2020/05/27 全球购物
小学节能减排倡议书
2014/05/15 职场文书
质量在我心中演讲稿
2014/09/02 职场文书
关于对大人不礼貌的检讨书
2014/09/29 职场文书
餐饮服务员岗位职责
2015/02/09 职场文书
幼儿园小班开学寄语(2016秋季)
2015/12/03 职场文书
2016年三八节红领巾广播稿
2015/12/17 职场文书
学生会2016感恩节活动小结
2016/04/01 职场文书
Python Django / Flask如何使用Elasticsearch
2022/04/19 Python
python+pyhyper实现识别图片中的车牌号思路详解
2022/12/24 Python