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中使用cookielib和urllib2配合PyQuery抓取网页信息
Apr 25 Python
使用Python对Csv文件操作实例代码
May 12 Python
flask中主动抛出异常及统一异常处理代码示例
Jan 18 Python
Python数据可视化教程之Matplotlib实现各种图表实例
Jan 13 Python
Python中使用双下划线防止类属性被覆盖问题
Jun 27 Python
python中的列表与元组的使用
Aug 08 Python
Python input函数使用实例解析
Nov 22 Python
如何通过命令行进入python
Jul 06 Python
Pytorch框架实现mnist手写库识别(与tensorflow对比)
Jul 20 Python
Python Selenium实现无可视化界面过程解析
Aug 25 Python
浅谈anaconda python 版本对应关系
Oct 07 Python
pycharm + django跨域无提示的解决方法
Dec 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
人大复印资料处理程序_查询篇
2006/10/09 PHP
有关JSON以及JSON在PHP中的应用
2010/04/09 PHP
用PHP的超级变量$_GET获取HTML表单(Form) 数据
2011/05/07 PHP
thinkphp3.2.2实现生成多张缩略图的方法
2014/12/19 PHP
使用图灵api创建微信聊天机器人
2015/07/23 PHP
php 截取utf-8格式的字符串实例代码
2016/10/30 PHP
PHP CodeIgniter分页实例及多条件查询解决方案(推荐)
2017/05/20 PHP
Yii2框架中一些折磨人的坑
2019/12/15 PHP
javascript取消文本选定的实现代码
2010/11/14 Javascript
JS冒泡事件的快速解决方法
2013/12/16 Javascript
JS根据变量保存方法名并执行方法示例
2014/04/04 Javascript
如何用JavaScript定义一个类
2014/09/12 Javascript
transport.js和jquery冲突问题的解决方法
2015/02/10 Javascript
jQuery oLoader实现的加载图片和页面效果
2015/03/14 Javascript
利用JavaScript如何查询某个值是否数组内
2017/07/30 Javascript
vue多种弹框的弹出形式的示例代码
2017/09/18 Javascript
vue实现nav导航栏的方法
2017/12/13 Javascript
关于vue单文件中引用路径的处理方法
2018/01/08 Javascript
vue组件中watch props根据v-if动态判断并挂载DOM的问题
2019/05/12 Javascript
让IDE识别webpack的别名alias的实现方法
2020/05/06 Javascript
JavaScript Html实现移动端红包雨功能页面
2021/01/10 Javascript
python中将阿拉伯数字转换成中文的实现代码
2011/05/19 Python
python中关于日期时间处理的问答集锦
2013/03/08 Python
python生成器的使用方法
2013/11/21 Python
Python实现Mysql数据库连接池实例详解
2017/04/11 Python
Python 处理数据的实例详解
2017/08/10 Python
Python中列表list以及list与数组array的相互转换实现方法
2017/09/22 Python
Python 列表推导式需要注意的地方
2020/10/23 Python
python3中数组逆序输出方法
2020/12/01 Python
HTML5 input placeholder 颜色修改示例
2014/05/30 HTML / CSS
优秀大学生推荐信范文
2013/11/28 职场文书
人力资源经理自我评价
2014/01/04 职场文书
暑期社会实践学生的自我评价
2014/01/09 职场文书
给国外客户的邀请函
2014/01/30 职场文书
财务经理岗位职责范本
2015/04/08 职场文书
电频谱管理的原则是什么
2022/02/18 无线电