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 SQLAlchemy基本操作和常用技巧(包含大量实例,非常好)
May 06 Python
Python struct模块解析
Jun 12 Python
python操作redis的方法
Jul 07 Python
Python利用公共键如何对字典列表进行排序详解
May 19 Python
Python continue继续循环用法总结
Jun 10 Python
Django框架ORM数据库操作实例详解
Nov 07 Python
Python通过Pillow实现图片对比
Apr 29 Python
详解python中的lambda与sorted函数
Sep 04 Python
Python 实现键盘鼠标按键模拟
Nov 18 Python
pip install命令安装扩展库整理
Mar 02 Python
python 如何读、写、解析CSV文件
Mar 03 Python
Python 一键获取电脑浏览器的账号密码
May 11 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
如何解决CI框架的Disallowed Key Characters错误提示
2013/07/05 PHP
php中的strpos使用示例
2014/02/27 PHP
php使用cookie实现记住登录状态
2015/04/27 PHP
Centos 6.5系统下编译安装PHP 7.0.13的方法
2016/12/19 PHP
利用phpexcel对数据库数据的导入excel(excel筛选)、导出excel
2017/04/27 PHP
thinkphp5.1框架实现格式化mysql时间戳为日期的方式小结
2019/10/10 PHP
Stop SQL Server
2007/06/21 Javascript
checkbox 多选框 联动实现代码
2008/10/22 Javascript
jQuery 使用手册(二)
2009/09/23 Javascript
JavaScript 对象的属性和方法4种不同的类型
2010/03/19 Javascript
JavaScript window.document的属性、方法和事件小结
2012/10/24 Javascript
网页中可关闭的漂浮窗口实现可自行调节
2013/08/20 Javascript
javascript实现表单提交后,提交按钮不可用的方法
2015/04/18 Javascript
谈谈基于iframe、FormData、FileReader三种无刷新上传文件的方法
2015/12/03 Javascript
在页面中输出当前客户端时间javascript实例代码
2016/03/02 Javascript
JavaScript中的 attribute 和 jQuery中的 attr 方法浅析
2017/01/04 Javascript
JS简单获取日期相差天数的方法
2017/04/24 Javascript
微信小程序实现根据字母选择城市功能
2017/08/16 Javascript
angular2实现统一的http请求头方法
2018/08/13 Javascript
微信小程序导航栏滑动定位功能示例(实现CSS3的positionsticky效果)
2019/01/24 Javascript
Taro小程序自定义顶部导航栏功能的实现
2020/12/17 Javascript
[01:11:48]Fnatic vs IG 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
在Windows服务器下用Apache和mod_wsgi配置Python应用的教程
2015/05/06 Python
python使用PIL模块获取图片像素点的方法
2019/01/08 Python
python实现控制COM口的示例
2019/07/03 Python
python版百度语音识别功能
2019/07/09 Python
妙用itchat! python实现久坐提醒功能
2019/11/25 Python
Python实现列表中非负数保留,负数转化为指定的数值方式
2020/06/04 Python
Clarks英国官方网站:全球领军鞋履品牌
2016/11/26 全球购物
Wojas罗马尼亚网站:波兰皮鞋品牌
2018/11/01 全球购物
迎八一活动主题
2014/01/31 职场文书
优秀团员事迹材料1500字
2014/08/31 职场文书
2014基层党员批评与自我批评范文
2014/09/24 职场文书
2015年驾驶员工作总结
2015/04/29 职场文书
2016年寒假见闻
2015/10/10 职场文书
SpringBoot 整合mongoDB并自定义连接池的示例代码
2022/02/28 MongoDB