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