python代码,遍历目录下所有图片,从exif中读取日期,按照日期整理到对应月份的目录下,如果exif中没有日期,尝试从文件名中提取日期:

import os
import datetime
import shutil
from PIL import Image

# 定义源目录和目标目录
source_dir = "MY_PATH" # 请修改为你的源目录路径
target_dir = "MY_PATH" # 请修改为你的目标目录路径

# 遍历源目录下所有文件
for file_name in os.listdir(source_dir):
    # 获取完整的文件路径
    file_path = os.path.join(source_dir, file_name)
    # 判断是否是图片文件
    if not file_path.lower().endswith((".jpg", ".jpeg", ".png", ".gif")):
        continue # 跳过非图片文件
    # 尝试从exif中读取日期信息
    try:
        image = Image.open(file_path)
        exif_data = image.getexif()
        date_str = exif_data.get(36867) # 36867是DateTimeOriginal的标签编号
        if date_str:
            date_obj = datetime.datetime.strptime(date_str, "%Y:%m:%d %H:%M:%S") # 将字符串转换为datetime对象
        else:
            raise ValueError("No date in exif") # 如果exif中没有日期信息,抛出异常
    except Exception as e:
        print(f"Failed to get date from exif for {file_name}: {e}")
        # 尝试从文件名中提取日期信息,假设格式为yyyymmdd或yyyy-mm-dd或yyyy_mm_dd或yyyy.mm.dd等等(可以根据需要添加更多格式)
        try:
            date_str = file_name[:10] # 截取前10个字符作为日期字符串
            date_obj = datetime.datetime.strptime(date_str, "%Y%m%d") # 将字符串转换为datetime对象(如果不符合格式会抛出异常)
        except ValueError:
            try:
                date_obj = datetime.datetime.strptime(date_str, "%Y-%m-%d")
            except ValueError:
                try:
                    date_obj = datetime.datetime.strptime(date_str, "%Y_%m_%d")
                except ValueError:
                    try:
                        date_obj = datetime.datetime.strptime(date_str, "%Y.%m.%d")
                    except ValueError: 
                        print(f"Failed to get date from filename for {file_name}")
                        continue # 如果无法从文件名中提取日期信息,跳过该文件

    # 根据日期对象创建对应月份的子目录名称(可以根据需要修改格式)
    sub_dir_name = f"{date_obj.year}-{date_obj.month:02}"
    sub_dir_path = os.path.join(target_dir, sub_dir_name) 
    if not os.path.exists(sub_dir_path): 
        os.makedirs(sub_dir_path) # 如果子目录不存在,则创建之

    # 复制图片文件到对应月份的子目录下(可以选择移动而不是复制)
    shutil.copy(file_path, sub_dir_path)