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 time模块详解(常用函数实例讲解,非常好)
Apr 24 Python
Python代码调试的几种方法总结
Apr 15 Python
用Python编写web API的教程
Apr 30 Python
利用Python为iOS10生成图标和截屏
Sep 24 Python
flask + pymysql操作Mysql数据库的实例
Nov 13 Python
浅谈Python traceback的优雅处理
Aug 31 Python
Python发送邮件的实例代码讲解
Oct 16 Python
Python求正态分布曲线下面积实例
Nov 20 Python
PyTorch中的Variable变量详解
Jan 07 Python
python 实现单例模式的5种方法
Sep 23 Python
python使用re模块爬取豆瓣Top250电影
Oct 20 Python
python中zip()函数遍历多个列表方法
Feb 18 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
function.inc.php超越php
2006/12/09 PHP
PHP时间戳与日期之间转换的实例介绍
2013/04/19 PHP
解析PHP 使用curl提交json格式数据
2013/06/29 PHP
php使用cookie显示用户上次访问网站日期的方法
2015/01/26 PHP
Zend Framework入门教程之Zend_View组件用法示例
2016/12/09 PHP
ThinkPHP 模板引擎使用详解
2017/05/07 PHP
原始的js代码和jquery对比体会
2013/09/10 Javascript
深入探讨JavaScript、JQuery屏蔽网页鼠标右键菜单及禁止选择复制
2014/06/10 Javascript
javascript的BOM
2016/05/03 Javascript
js实现的在线调色板功能完整实例
2016/12/21 Javascript
JS轮播图实现简单代码
2021/02/19 Javascript
AngularJS 中ui-view传参的实例详解
2017/08/25 Javascript
Vue cli 引入第三方JS和CSS的常用方法分享
2018/01/20 Javascript
vue2 设置router-view默认路径的实例
2018/09/20 Javascript
js中this的指向问题归纳总结
2018/11/28 Javascript
html中创建并调用vue组件的几种方法汇总
2020/11/17 Javascript
[52:27]2018DOTA2亚洲邀请赛 3.31 小组赛B组 paiN vs Secret
2018/04/01 DOTA
Python常用的内置序列结构(列表、元组、字典)学习笔记
2016/07/08 Python
关于numpy中np.nonzero()函数用法的详解
2017/02/07 Python
python爬虫框架talonspider简单介绍
2017/06/09 Python
matplotlib调整子图间距,调整整体空白的方法
2018/08/03 Python
解决Python中定时任务线程无法自动退出的问题
2019/02/18 Python
Django用户认证系统 Web请求中的认证解析
2019/08/02 Python
Django 响应数据response的返回源码详解
2019/08/06 Python
详解python中docx库的安装过程
2019/11/08 Python
python ftplib模块使用代码实例
2019/12/31 Python
对pytorch中x = x.view(x.size(0), -1) 的理解说明
2021/03/03 Python
css3实现蒙版弹幕功能
2019/06/18 HTML / CSS
中科软测试工程师面试题
2012/06/16 面试题
Ajax实现页面无刷新留言效果
2021/03/24 Javascript
竞争与合作演讲稿
2014/05/12 职场文书
三好学生个人先进事迹材料
2014/05/17 职场文书
岗位职责说明书模板
2014/07/30 职场文书
2015年度销售个人工作总结
2015/03/31 职场文书
毕业论文答辩演讲稿
2015/06/23 职场文书
Golang二维切片初始化的实现
2021/04/08 Golang