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用list或dict字段模式读取文件的方法
Jan 10 Python
OpenCV实现人脸识别
Apr 07 Python
深入理解python中的select模块
Apr 23 Python
Ubuntu下使用python读取doc和docx文档的内容方法
May 08 Python
Python线性拟合实现函数与用法示例
Dec 13 Python
python3中numpy函数tile的用法详解
Dec 04 Python
在notepad++中实现直接运行python代码
Dec 18 Python
Tensorflow的梯度异步更新示例
Jan 23 Python
详解pandas.DataFrame.plot() 画图函数
Jun 14 Python
基于python实现操作git过程代码解析
Jul 27 Python
python中if嵌套命令实例讲解
Feb 25 Python
使用Python webdriver图书馆抢座自动预约的正确方法
Mar 04 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
如何限制访问者的ip(PHPBB的代码)
2006/10/09 PHP
PHP中的正规表达式(一)
2006/10/09 PHP
PHP date函数参数详解
2006/11/27 PHP
Discuz!5的PHP代码高亮显示插件(黑暗中的舞者更新)
2007/01/29 PHP
用PHP实现的四则运算表达式计算实现代码
2011/08/02 PHP
Laravel 5框架学习之Laravel入门和新建项目
2015/04/07 PHP
Ubuntu server 11.04安装memcache及php使用memcache来存储session的方法
2016/05/31 PHP
PHP获取远程http或ftp文件的md5值的方法
2019/04/15 PHP
javascript中的location用法简单介绍
2007/03/07 Javascript
javascript 模式设计之工厂模式学习心得
2010/04/27 Javascript
javascript结合Canvas 实现简易的圆形时钟
2015/03/11 Javascript
原生js编写焦点图效果
2016/12/08 Javascript
bootstrap daterangepicker汉化以及扩展功能
2017/06/15 Javascript
使用 Javascript 实现浏览器推送提醒功能的示例
2017/11/03 Javascript
在vue中封装可复用的组件方法
2018/03/01 Javascript
jQuery实现遍历XML节点和属性的方法示例
2018/04/29 jQuery
webpack实现一个行内样式px转vw的loader示例
2018/09/13 Javascript
vue App.vue中的公共组件改变值触发其他组件或.vue页面监听
2019/05/31 Javascript
js Array.slice的8种不同用法示例
2019/07/10 Javascript
基于Vue全局组件与局部组件的区别说明
2020/08/11 Javascript
Python中DJANGO简单测试实例
2015/05/11 Python
python使用代理ip访问网站的实例
2018/05/07 Python
使用selenium模拟登录解决滑块验证问题的实现
2019/05/10 Python
ZABBIX3.2使用python脚本实现监控报表的方法
2019/07/02 Python
Python实现简单的列表冒泡排序和反转列表操作示例
2019/07/10 Python
flask/django 动态查询表结构相同表名不同数据的Model实现方法
2019/08/29 Python
在python中利用try..except来代替if..else的用法
2019/12/19 Python
HTML5事件方法全部汇总
2016/05/12 HTML / CSS
HTML5之语义标签介绍
2016/07/07 HTML / CSS
澳大利亚游乐场设备品牌:Lifespan Kids
2019/05/24 全球购物
怎样写好自我评价呢?
2014/02/16 职场文书
城市创卫标语
2014/06/17 职场文书
表扬稿表扬信的格式及范文
2019/06/24 职场文书
用Python爬虫破解滑动验证码的案例解析
2021/05/06 Python
MySQL 8.0 Online DDL快速加列的相关总结
2021/06/02 MySQL
Android开发EditText禁止输入监听及InputFilter字符过滤
2022/06/10 Java/Android