python 下载文件的几种方式分享

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 下载文件的资料请关注我们其它相关文章!

(0)

相关推荐

  • python基于paramiko库远程执行 SSH 命令,实现 sftp 下载文件

    楔子 我们使用 Python 避免不了和 Linux 打交道,而有时我们需要执行一些 shell 命令.如果在本地的话,那么可以通过调用 os.system 或者 subprocess.Popen 来执行,但如果我们希望远程执行其它机器上的 shell 命令,这个时候该怎么做呢?下面我们就来推荐一个第三方库 paramiko,看看如何使用 Python 远程操作其它机器. paramiko 网络传输是遵循协议的,比如 SSH,paramiko 则是实现了 SSHv2 协议的一个 Python 第

  • python 下载文件的几种方法汇总

    前言 使用脚本进行下载的需求很常见,可以是常规文件.web页面.Amazon S3和其他资源.Python 提供了很多模块从 web 下载文件.下面介绍 一.使用 requests requests 模块是模仿网页请求的形式从一个URL下载文件 示例代码: import requests url = 'xxxxxxxx' # 目标下载链接 r = requests.get(url) # 发送请求 # 保存 with open ('r.txt', 'rb') as f: f.write(r.con

  • python爬虫智能翻页批量下载文件的实例详解

    python爬虫遇到爬取文件内容时,需要一页页的翻页爬取,这样很是麻烦,其实可以获取每个列表信息下的文件名和文件链接,让文件名和文件链接处理为列表,保存后下载,实现智能翻页批量下载文件,本文以以京客隆为例,批量下载文件,如财务资料,他的每一份报告都是一份pdf格式的文档.以此页面为目标,下载他每个分类的文件python爬虫实战之智能翻页批量下载文件. 1.引入库 import requests import pandas as pd from lxml import etree import r

  • Python实现FTP文件定时自动下载的步骤

    之前遇到技术问题总能在技术博客上得到启发,十分感谢各位的无私分享.而自己却很少发文,固然是水平有限,但也限制了知识积累和总结.今后多总结分享,回馈博客的同时也希望大家多多批评. 一.需求: 某数据公司每日15:00~17:00之间,在其FTP发布当日数据供下载,我方需及时下载当日数据至指定本地目录. 二.分析: 1.需实现FTP登陆.查询.下载功能: 解答:使用内置的ftplib模块中FTP类: 2.需判断文件是否下载: 解答:使用os模块中path.exists方法: 3.需判断在指定时间段内

  • Python解析m3u8拼接下载mp4视频文件的示例代码

    一.关于m3u8: m3u8是苹果公司推出一种视频播放标准,是m3u的一种,不过编码方式是utf-8,是一种文件检索格式,将视频切割成一小段一小段的ts格式的视频文件,然后存在服务器中(现在为了减少I/o访问次数,一般存在服务器的内存中),通过m3u8解析出来路径,然后去请求. 示例: #EXTM3U #EXT-X-TARGETDURATION:10 #EXTINF:9, http://data.video.iqiyi.com/videos/vts/20210301/69/b8/73ad4ef0

  • Python 使用SFTP和FTP实现对服务器的文件下载功能

    一.用 ftplib 模块连接远程服务器 ftplib模块常用方法 ftp登陆连接 from ftplib import FTP #加载ftp模块 ftp=FTP() #设置变量 ftp.set_debuglevel(2) #打开调试级别2,显示详细信息 ftp.connect("IP","port") #连接的ftp sever和端口 ftp.login("user","password") #连接的用户名,密码 print

  • Python根据URL地址下载文件并保存至对应目录的实现

    引言 在编程中经常会遇到图片等数据集将图片等数据以URL形式存储在txt文档中,为便于后续的分析,需要将其下载下来,并按照文件夹分类存储.本文以Github中Alexander Kim提供的图片分类数据集为例,下载其提供的图片样本并分类保存 Python 3.6.5,Anaconda, VSCode 1. 下载数据集文件 建立项目文件夹,下载上述Github项目中的raw_data文件夹,并保存至项目目录中.  2. 获取样本文件位置 编写get_doc_path.py,根据根目录位置,获取目录

  • python从ftp获取文件并下载到本地

    最近有需求是,需要把对方提供的ftp地址上的图片获取到本地服务器,原先计划想着是用shell 操作,因为shell 本身也支持ftp的命令 在通过for 循环也能达到需求.但是后来想着 还是拿python 操作:于是在网上进行百度:无一例外 还是那么失望 无法直接抄来就用.于是在一个代码上进行修改.还是有点心东西学习到了:具体操作代码如下 只要修改ftp 账号密码 已经对应目录即可使用 在这需要注意一点的是os.path.join 的用法需要注意 #!/usr/bin/python # -*-

  • 用Python自动下载网站所有文件

    最近维基 jie mi 彻底公开了网站的全部文件,我就在想如何使用 Python 将其下载到本地永久保存,于是就有了这篇文章,写爬虫会遇到很多坑,借鉴他人经验,考虑越全面,出错的概率就越小. 假如一个网站,里面有很多链接,有指向文件的,有指向新链接的,新的链接点击进去后,仍然是有指向文件的,有指向新链接的,类似一个文件夹,里面即有文件,又有目录,目录中又有文件和目录.如何从这样的网站上下载所有的文件,并按网站的目录结构来保存这些文件呢? 关键词:Python.下载.正则表达式.递归. 按照自顶向

  • python 基于selectors库实现文件上传与下载

    server.py import selectors import socket import os import time BASE_DIR =os.path.abspath(os.path.dirname(__file__)) class selectFtpserver: def __init__(self): self.dic = {} # 创建空字典 self.hasReceived = 0 self.hasSend=0 self.sel = selectors.DefaultSelec

随机推荐