python通过requests下载图片存到指定目录并生成缩略图


使用python,下载图片存到指定目录并生成缩略图
返回元组

import os
import requests
from PIL import Image
from io import BytesIO
import hashlib
import time
import random


'''
通过文件地址爬取图片文件,压缩文件,将两个文件存储在当前目录下
返回原因,原始图片和缩略图的相对路径地址
'''
def download_and_compress_image(url, filename, folder, subFolder=None, maxWidth=100):

    #拓展名
    extension = 'jpg'
    if '.' in os.path.basename(url):
        extension = os.path.basename(url).split('.')[-1].split('?')[0]

    #文件名(不含拓展名):
    filename = filename if filename is not None else f"{hashlib.md5(url.encode()).hexdigest()}"

    # 替换Windows不支持的文件名为横线杠  
    forbidden_chars = '<>:"/\\|?*'
    # Characters not allowed in Windows filenames
    if filename:
        for char in forbidden_chars:
            filename = filename.replace(char, '-')

    # Characters not allowed in Windows filenames
    if folder:
        for char in forbidden_chars:
            folder = folder.replace(char, '-')

    # Characters not allowed in Windows filenames
    if subFolder:
        for char in forbidden_chars:
            subFolder = subFolder.replace(char, '-')

        
    if subFolder:
        imageDir = os.path.join(f'{folder}_image_src', subFolder)
        thumbDir = os.path.join(f'{folder}_thumbnail_{maxWidth}', subFolder)


    # 确保image和thumb目录存在
    os.makedirs(imageDir, exist_ok=True)
    os.makedirs(thumbDir, exist_ok=True)
    
    # 初始化返回的路径
    imagePath = os.path.join(imageDir, filename)
    thumbPath = os.path.join(thumbDir, filename)  # 总是提供缩略图路径

    imagePath = f'{imagePath}.{extension}'
    thumbPath = f'{thumbPath}.{extension}'
    #print(imagePath,thumbPath)


    # 如果文件不存在,则下载并保存 image src
    if not os.path.exists(imagePath)or not os.stat(imagePath).st_size:
        # 下载图片
        try:
            response = requests.get(url)
        except requests.exceptions.SSLError as ee:
            return (ee, None, None)
        except requests.exceptions.ReadTimeout as ee:
            return (ee, None, None)

        #休息三秒钟内
        time.sleep(random.randint(1,3))
            
        if not response.status_code == 200:
            #print(f"图片下载失败,状态码:{response.status_code}")
            return (f'http code errr{response.status_code}', None,None)
        
        #print(f'file down and save:{file_path}')
    
        # 使用BytesIO暂时保存图片数据
        byte_stream = BytesIO(response.content)
    
        # 使用Pillow打开图片
        img = Image.open(byte_stream)
        
        # 保存原始图片到img目录下
        img.save(imagePath)
    else:
        #print('source image exists to skip')
        pass


    
    
    # 如果文件不存在,则下载并保存 thumbnail
    if not os.path.exists(thumbPath) or not os.stat(thumbPath).st_size:
        # 打开文件并读取内容
        with open(imagePath, 'rb') as file:
            # 创建一个BytesIO对象,并将文件内容写入其中
            byte_stream = BytesIO(file.read())
            
        # 使用Pillow打开图片
        img = Image.open(byte_stream)
    
        # 对所有图片进行压缩处理,即使它们已经小于或等于100px
        # 计算压缩后的尺寸,保持宽高比
        ratio = min(maxWidth/img.width, maxWidth/img.height)
        new_size = (int(img.width * ratio), int(img.height * ratio))
        #img.thumbnail(new_size, Image.ANTIALIAS)
        img.thumbnail(new_size, Image.LANCZOS)
        
        # 保存压缩后的图片到thumb目录下
        img.save(thumbPath)
        
        #print(f'resize:{srcWidth}x{srcHeight}->{img.height}x{img.width}')
    else:
        #print('thumb exists to skip')
        pass
    
    # 返回原图和缩略图的相对路径元组
    return ('success', imagePath, thumbPath)







if __name__ == "__main__":
    # 这部分代码只会在该模块作为脚本直接运行时执行

    # 示例使用
    url = 'https://tt.yongit.com/stated/default/logo.png'  # 请替换为实际的图片URL
    #url = 'https://cdn.shopify.com/s/files/1/2999/8094/files/9-2_d38c5764-eae6-4860-b874-cfda2ff2436f.webp?v=1708943502'
    filename = 'examplex'

    try:
        res = download_and_compress_image(url, 'filename_only', 'test.example.com','subfolder',150)
    except requests.exceptions.SSLError as ee:
        res = (ee, None, None)
        
    print(res)


    pass
else:
    # 这部分代码只会在该模块被其他模块导入时执行
    pass




原文链接:https://blog.yongit.com/note/1573045.html