文件下载

  • 1. 小文件下载
  • 2. 大文件下载
  • 3. 异步批量文件下载


1. 小文件下载

基于requests模块的get()函数下载。下载原理如下:先将文件内容保存至变量(即设备内存)中,然后再保存至指定文件中。这种下载有一个最大的限制是内存大小。

python抖音怎么批量下载视频 python 批量下载_写入文件

import requests

def request_zip(url):
    rc = requests.get(url)
    # 请求链接后保存到链接变量 rc 中
    with open("Download_test.jpg", 'wb') as fout:
        # rc.content 写入文件
        fout.write(rc.content)

if __name__ == '__main__':
    url = "https://pic3.zhimg.com/80/v2-9add4b1033b586a16afd567647326441_720w.jpg"
    request_zip(url)

2. 大文件下载

不同于小文件下载,如果将待下载数据保存至内存中,然后再提取保存至本地文件,会因内存的大小受到限制,甚至中断下载。

对于大文件的下载:采用分块方法,将文件按照指定大小,逐块下载数据并写入的指定文件,避免占用过大内存。

python抖音怎么批量下载视频 python 批量下载_文件下载_02

import requests

def request_zip(url):
    rc = requests.get(url)
    # 请求链接后保存到链接变量 rc 中
    with open("Download_test.jpg", 'wb') as fout:
        # rc.content 写入文件
        fout.write(rc.content)

def download_bigData(url):
    # stream = True 设置为流读取
    rg = requests.get(url, stream=True)
    with open("Download_bigTest.jpg", "wb") as fout:
        for chunk in rg.iter_content(chunk_size=256):
            # 以256个字节为一块,读取文件
            if chunk:
                # 如果chunk不为空
                fout.write(chunk)
if __name__ == '__main__':
    url = "https://pic3.zhimg.com/80/v2-9add4b1033b586a16afd567647326441_720w.jpg"
    # request_zip(url)
    download_bigData(url)

3. 异步批量文件下载

所谓批量下载,非一个一个文件的下载,如果一个一个下载会出现两种负面情况:

  • 如果某个请求堵塞,整个队列都会被堵塞
  • 如果是小文件,单线程下载太慢

解决方案是使用 异步策略。接下来,我们来讲解如何手动实现异步策略。

  1. 安装模块
  • asyncio
  • aiohttp. asyncio (Python3的原装库),但是aiohttp则需要手动安装:
    pip install aiohttp
    注意 :asyncio是单进程并发库,不是多线程,也不是多进程,单纯是在一个进程里面异步(切来切去运行),切换的地方用await标记,能够切换的函数用async标记。比如异步批量下载两个图片的代码如下:
import requests

import aiohttp
import asyncio
import time

def request_zip(url):
    rc = requests.get(url)
    # 请求链接后保存到链接变量 rc 中
    with open("Download_test.jpg", 'wb') as fout:
        # rc.content 写入文件
        fout.write(rc.content)

def download_bigData(url):
    # stream = True 设置为流读取
    rg = requests.get(url, stream=True)
    with open("Download_bigTest.jpg", "wb") as fout:
        for chunk in rg.iter_content(chunk_size=256):
            # 以256个字节为一块,读取文件
            if chunk:
                # 如果chunk不为空
                fout.write(chunk)


async def job(session, url):
    # 声明为异步函数
    name = url.split('/')[-1]
    # 获得名字
    img = await session.get(url)
    # 触发到await就切换,等待get到数据
    imgcode = await img.read()
    # 读取内容
    with open(str(name), "wb") as fout:
        # 写入文件
        fout.write(imgcode)
    return str(url)

async def main(loop, url):
    async with aiohttp.ClientSession() as session:
        # 建立会话 session
        tasks = [loop.create_task(job(session, url[_])) for _ in range(2)]
        # 建立所有任务
        finshed, unfinshed = await asyncio.wait(tasks)
        # 触发await,等待任务完成
        all_results = [r.result() for r in finshed]
        # 获取所有结果
        print("ALL RESULTS:" + str(all_results))

if __name__ == '__main__':
    # url = "https://pic3.zhimg.com/80/v2-9add4b1033b586a16afd567647326441_720w.jpg"
    # request_zip(url)
    # download_bigData(url)

    urllst = ["https://pic3.zhimg.com/80/v2-999dedf65c41973c21e05e435c2ee536_720w.jpg", \
              "https://picb.zhimg.com/80/v2-3dc4b27d86e5b870074898cf6532efee_720w.jpg"]
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main(loop, urllst))

注意:img = await session.get(url)
这时候,在你请求第一个图片获得数据的时候,它会切换请求第二个图片或其他图片,等第一个图片获得所有数据后再切换回来。从而实现多线程批量下载的功能,速度超快,下载超清大图用这个方法可以一秒一张。