
一、背景需求
有一年的照片没有导出手机,手机卡顿,终于坐办公室了,有时间把照片导出做整理,清空手机内存。

二、华为手机助手,导出照片
我把照片导入D盘的"02照片导出"文件夹

但是全选导出有2.7万张照片,很容易断掉。
也不知道复制到哪一天,然后又需要重新全选。
所以最好一个月一个月内容复制。
本次学到用隐藏按钮,可以只显示照片所在的日期范围。选一个月的照片

这样比较稳定,安全

三、代码导出图片并转入相应文件夹
python
'''
1、华为手机助手导出的照片,根据照片、视频的文件名中的日期,提取日期,转移到日期文件夹中
2、将日期文件夹复制到"年-年月-年月日"文件夹内
IMG_20240428_085357.jpg
VID_20240603_131241.mp4
如果文件已存在,就替换它
作者:文心一言,阿夏
时间:2024年10月31日
'''
import os
import re
from datetime import datetime
import shutil
folder_path = r'D:\02照片导出'
new_folder = r'D:\03照片整理'
os.makedirs(new_folder, exist_ok=True)
file_names = os.listdir(folder_path)
for file_name in file_names:
split_name = re.split("_", file_name)
if len(split_name[1]) == 8:
date_obj = datetime.strptime(split_name[1], "%Y%m%d")
new_folder_name = date_obj.strftime("%Y-%m-%d")
print(new_folder_name)
new_folder_path = os.path.join(new_folder, new_folder_name)
os.makedirs(new_folder_path, exist_ok=True)
target_path = os.path.join(new_folder_path, file_name)
shutil.move(os.path.join(folder_path, file_name), target_path)
elif len(split_name[1]) == 3:
date_obj = datetime.strptime(split_name[2][:8], "%Y%m%d")
new_folder_name = date_obj.strftime("%Y-%m-%d")
print(new_folder_name)
new_folder_path = os.path.join(new_folder, new_folder_name)
os.makedirs(new_folder_path, exist_ok=True)
target_path = os.path.join(new_folder_path, file_name)
shutil.move(os.path.join(folder_path, file_name), target_path)
else:
pass
import os
import shutil
# 设置源文件夹路径
source_folder =new_folder
new= new_folder
os.makedirs(new,exist_ok=True)
# 遍历源文件夹下的所有子文件夹
for folder in os.listdir(source_folder):
folder_path = os.path.join(source_folder, folder)
# 检查是否是文件夹并且长度是10
if os.path.isdir(folder_path) and len(folder) == 10:
# 提取年、月、日
year = folder[0:4]
month = str(folder[5:7])
day = folder[8:10]
# 创建目标文件夹路径
target_folder =new+f'\{year}年\{year}年{month}月'
# 检查目标文件夹是否存在
if not os.path.exists(target_folder):
os.makedirs(target_folder)
# 如果目标文件夹不存在,直接移动整个文件夹
shutil.move(folder_path, target_folder)
print(f'Moved {folder} to {target_folder}')
else:
# 如果目标文件夹存在,合并文件夹内容
target_subfolder = os.path.join(target_folder, folder) # 尝试创建同名子文件夹路径
if not os.path.exists(target_subfolder):
os.makedirs(target_subfolder) # 如果不存在,则创建
# 遍历源文件夹中的所有文件,并复制到目标子文件夹中
for root, dirs, files in os.walk(folder_path):
for file in files:
src_file = os.path.join(root, file)
dst_file = os.path.join(target_subfolder, file)
# 复制文件,如果文件已存在,可以选择覆盖(shutil.copy2)或跳过(使用异常处理)
try:
shutil.copy2(src_file, dst_file) # 使用shutil.copy2保留元数据
except FileExistsError:
print(f'Skipped {file} (already exists in {target_subfolder})')
# 可选:如果源文件夹中还有子文件夹,可以递归处理它们
# 但在这个特定案例中,我们假设文件夹结构是平的,即没有嵌套子文件夹
# 删除空的源文件夹(如果所有文件都已复制)
shutil.rmtree(folder_path) # 注意:这只有在确认所有文件都已正确复制后才安全执行
print(f'Merged {folder} into {target_subfolder}')




最后一套,我就博一下,七千张全选



终于全部导出了


全部分类完成




三、指定文件夹里添加统一名称的文件夹
这两天我去大班教室、中班教室拍摄希沃显示屏,掌握各班希沃白板的使用情况(适合幼儿操作-柜子遮挡、是否可插U盘、浏览器选择和HTML学具页面效果)
照片已经导出,但是照片需要按班级分类 
制作班级文件夹(难得有一个我可以自己手写的代码)
python
import os
path=r'D:\03照片整理\2026年\2026年10月\2026-10-30'
for i in range(1,7):
a=f'中{i}班的希沃显示屏'
b=path+fr'\{a}'
os.makedirs(b,exist_ok=True)

把班牌的照片为分割点,照片拖入文件夹

同理制作大班的文件夹
python
import os
path=r'D:\03照片整理\2026年\2026年10月\2026-10-29'
for i in range(1,6):
a=f'大{i}班的希沃显示屏'
b=path+fr'\{a}'
os.makedirs(b,exist_ok=True)


四、文件夹手动更名
我需要再在每个文件夹里增加5个文件夹(20261026(1)、20261026(2)),来分类照片。



python
'''
读取123文件下的所有三级文件夹的文件名(都是日期如20261001),
然后在三级里面制作6个四级文件夹,
文件名是20261001_01\20261001_02\20261001_03\20261001_06等
deepseek,阿夏
20261031
'''
import os
# 根目录
root_dir = r"D:\03照片整理"
# 要创建的四级文件夹后缀
suffixes = ["01", "02", "03", "04", "05", "06"]
# 遍历根目录
for level1 in os.listdir(root_dir):
path1 = os.path.join(root_dir, level1)
if not os.path.isdir(path1):
continue
for level2 in os.listdir(path1):
path2 = os.path.join(path1, level2)
if not os.path.isdir(path2):
continue
for level3 in os.listdir(path2):
path3 = os.path.join(path2, level3)
if not os.path.isdir(path3):
continue
# 三级文件夹名就是日期,如 20261001
date_name = level3
# 在三级文件夹里创建6个四级文件夹
for suffix in suffixes:
new_folder = os.path.join(path3, f"{date_name}_{suffix}")
os.makedirs(new_folder, exist_ok=True)
print(f"已创建: {new_folder}")
print("全部完成!")


但是我希望文件名的日期里面没有"-"

python
'''
读取123文件下的所有三级文件夹的文件名(都是日期如20261001),
然后在三级里面制作6个四级文件夹,
文件名是20261001_01\20261001_02\20261001_03\20261001_06等
deepseek,阿夏
20261031
'''
import os
# 根目录
root_dir = r"D:\03照片整理"
# 要创建的四级文件夹后缀
suffixes = ["01", "02", "03", "04", "05", "06"]
# 遍历根目录
for level1 in os.listdir(root_dir):
path1 = os.path.join(root_dir, level1)
if not os.path.isdir(path1):
continue
for level2 in os.listdir(path1):
path2 = os.path.join(path1, level2)
if not os.path.isdir(path2):
continue
for level3 in os.listdir(path2):
path3 = os.path.join(path2, level3)
if not os.path.isdir(path3):
continue
# 三级文件夹名就是日期,如 20261001
date_name = level3
# 在三级文件夹里创建6个四级文件夹
for suffix in suffixes:
new_folder = os.path.join(path3, f"{date_name}-{suffix}")
os.makedirs(new_folder, exist_ok=True)
print(f"已创建: {new_folder}")
print("全部完成!")

不对,它还是yyyy-mm-dd格式,我要yyyymmdd-01的格式


这下终于对了
python
'''
读取123文件下的所有三级文件夹的文件名(都是日期如20261001),
然后在三级里面制作6个四级文件夹,
文件名是20261001_01\20261001_02\20261001_03\20261001_06等
deepseek,阿夏
20261031
'''
import os,re
# 根目录
root_dir = r"D:\03照片整理"
suffixes = ["01", "02", "03", "04", "05", "06"]
for level1 in os.listdir(root_dir):
path1 = os.path.join(root_dir, level1)
if not os.path.isdir(path1):
continue
for level2 in os.listdir(path1):
path2 = os.path.join(path1, level2)
if not os.path.isdir(path2):
continue
for level3 in os.listdir(path2):
path3 = os.path.join(path2, level3)
if not os.path.isdir(path3):
continue
# 把三级文件夹名里的非数字字符去掉,得到 20261001
date_name = re.sub(r"\D", "", level3) # \D = 非数字
# 如果去掉后不是8位数字,说明不是日期文件夹,跳过
if len(date_name) != 8 or not date_name.isdigit():
print(f"跳过非日期文件夹: {path3}")
continue
# 创建 20261001-01 这种四级文件夹
for suffix in suffixes:
new_folder = os.path.join(path3, f"{date_name}-{suffix}")
os.makedirs(new_folder, exist_ok=True)
print(f"已创建: {new_folder}")
print("全部完成!")

但是之前已经做了6+6个文件夹,需要批量删除

python
'''
删除文件名是2026-10-01_01\2026-10-01---01的错误文件夹
deepseek,阿夏
20261031
'''
import os
import re
import shutil
root_dir = r"D:\03照片整理"
# 匹配:8位或带分隔符的日期 + 分隔符(_ 或 -) + 两位编号
# 例:2026-10-01_01 / 2026-10-01-01 / 20261001_01 / 20261001-01
pattern = re.compile(r"^\d{4}[-_.]?\d{2}[-_.]?\d{2}[-_]\d{2}$")
# ===== 第一步:预览(只打印,不删除)=====
print("=== 预览待删除文件夹 ===")
targets = []
for dirpath, dirnames, filenames in os.walk(root_dir):
for d in dirnames:
if pattern.match(d):
full = os.path.join(dirpath, d)
targets.append(full)
print(full)
print(f"\n共找到 {len(targets)} 个待删除文件夹")
# ===== 第二步:确认后删除 =====
if targets:
confirm = input("确认删除以上文件夹?输入 yes 继续:").strip().lower()
if confirm == "yes":
for t in targets:
try:
shutil.rmtree(t)
print(f"已删除: {t}")
except Exception as e:
print(f"删除失败 {t}: {e}")
print("删除完成!")
else:
print("已取消,未删除任何文件。")
else:
print("没有匹配的文件夹。")

486个日期文件夹里共有8754个需要文件夹删除,5秒就全部删光


再运行一次06

486个日期文件夹 ,用AI批量添加文件夹,只要2秒,比人工添加文件夹不知道快几百倍。


接下去就是人工分类照片的时间,非常费时间,一天就能整理最多2个月的数据。
六、补充三级文件夹名称,
把四级文件夹的名称合并,补充三级文件夹的文件名












再做两份

再运行一次

没能修改成功



python
'''
Python,读取123下面的三级文件夹下面的多个四级文件夹,提取每个文件夹的名称(如20261001_志愿者,就提取志愿者几个字)进行合并(如志愿者、户外运动、学习活动),然后在三级文件夹的日期的后面把这些添加上2026-10-01 志愿者、户外运动、学习活动
deepseek,阿夏
20261031
'''
import os
import re
# 你的根目录
root_dir = r"D:\03照片整理"
# 修改核心:提取四级文件夹的内容
# 解释:(?:\d{8}[-_]?|.*?) 匹配 8位日期(可带横杠/下划线) 或者 前面的杂乱字符
# 后面的 ([\u4e00-\u9fa5a-zA-Z0-9]+) 匹配并提取中文/英文/数字
sub_pattern = re.compile(r"^(?:\d{8}[-_]?|.*?)([\u4e00-\u9fa5a-zA-Z0-9]+)$")
def get_base_name(level3):
"""
取三级文件夹名的前10个字符作为基础名(保留日期部分)。
若前10个字符不是合法日期格式,则回退到正则提取。
"""
prefix = level3[:10]
# 校验前10个字符是否形如 YYYY-MM-DD / YYYY_MM_DD / YYYY.MM.DD / YYYYMMDD..
if re.match(r"^\d{4}[-_.]?\d{2}[-_.]?\d{2}$", prefix):
return prefix
# 回退:用正则提取开头的日期
m = re.match(r"^(\d{4}[-_.]?\d{2}[-_.]?\d{2})", level3)
if m:
return m.group(1)
return None
# ===== 第一步:预览 =====
print("=== 预览重命名结果 ===\n")
tasks = []
for level1 in os.listdir(root_dir):
path1 = os.path.join(root_dir, level1)
if not os.path.isdir(path1):
continue
for level2 in os.listdir(path1):
path2 = os.path.join(path1, level2)
if not os.path.isdir(path2):
continue
for level3 in os.listdir(path2):
path3 = os.path.join(path2, level3)
if not os.path.isdir(path3):
continue
# 取三级文件夹前10个字符作为日期基础名
date_name = get_base_name(level3)
if not date_name:
print(f"[跳过] 无法识别日期: {path3}")
continue
# 遍历四级文件夹,提取名称
extracted = []
for sub in os.listdir(path3):
sub_path = os.path.join(path3, sub)
if not os.path.isdir(sub_path):
continue
# 使用新的正则匹配四级文件夹名
sm = sub_pattern.match(sub)
if sm:
name = sm.group(1).strip()
# 过滤掉空字符串和纯数字,防止把类似 "01" 也提取进去
if name and not name.isdigit() and name not in extracted:
extracted.append(name)
if not extracted:
print(f"[跳过] 无有效四级文件夹: {path3}")
continue
# 合并提取到的名称
merged = "、".join(extracted)
new_name = f"{date_name} {merged}" # 日期 + 空格 + 合并名
new_path = os.path.join(path2, new_name)
# 如果新名字和老名字一样,就不处理了
if level3 == new_name:
continue
tasks.append((path3, new_path, level3, new_name))
print(f"原名: {level3}")
print(f"新名: {new_name}\n")
# ===== 第二步:确认后重命名 =====
if tasks:
confirm = input(f"共 {len(tasks)} 个文件夹待重命名,输入 yes 执行:").strip().lower()
if confirm == "yes":
# 两阶段重命名:先改成临时名,避免新旧名字冲突
temp_list = []
for i, (old, new, _, _) in enumerate(tasks):
temp = old + f"__tmp_{i}"
try:
os.rename(old, temp)
temp_list.append((temp, new))
except Exception as e:
print(f"失败 {old}: {e}")
for temp, new in temp_list:
try:
if os.path.exists(new):
print(f"[跳过] 目标已存在: {new}")
continue
os.rename(temp, new)
print(f"已重命名 → {os.path.basename(new)}")
except Exception as e:
print(f"失败 {temp}: {e}")
print("\n完成!")
else:
print("已取消。")
else:
print("没有需要处理的文件夹。")

再做一个文件夹(内部所有文件夹都做好)


再做一次测试,一个文件夹里面只做其中一个文件夹,其他照片不做




更新2个文件夹汉字名字+4个数字文件夹(空)





还有两个手动制作的文件夹,文件名太长了且重复





改用直接运行,不要输入yes
python
'''
Python,读取123下面的三级文件夹下面的多个四级文件夹,提取每个文件夹的名称(如20261001_志愿者,就提取志愿者几个字)进行合并(如志愿者、户外运动、学习活动),然后在三级文件夹的日期的后面把这些添加上2026-10-01 志愿者、户外运动、学习活动
deepseek,阿夏
20261031
'''
import os
import re
# 你的根目录
root_dir = r"D:\03照片整理"
# 修改核心:提取四级文件夹的内容
# 解释:(?:\d{8}[-_]?|.*?) 匹配 8位日期(可带横杠/下划线) 或者 前面的杂乱字符
# 后面的 ([\u4e00-\u9fa5a-zA-Z0-9]+) 匹配并提取中文/英文/数字
sub_pattern = re.compile(r"^(?:\d{8}[-_]?|.*?)([\u4e00-\u9fa5a-zA-Z0-9]+)$")
def get_base_name(level3):
"""
取三级文件夹名的前10个字符作为基础名(保留日期部分)。
若前10个字符不是合法日期格式,则回退到正则提取。
"""
prefix = level3[:10]
# 校验前10个字符是否形如 YYYY-MM-DD / YYYY_MM_DD / YYYY.MM.DD / YYYYMMDD..
if re.match(r"^\d{4}[-_.]?\d{2}[-_.]?\d{2}$", prefix):
return prefix
# 回退:用正则提取开头的日期
m = re.match(r"^(\d{4}[-_.]?\d{2}[-_.]?\d{2})", level3)
if m:
return m.group(1)
return None
# ===== 第一步:预览 =====
print("=== 预览重命名结果 ===\n")
tasks = []
for level1 in os.listdir(root_dir):
path1 = os.path.join(root_dir, level1)
if not os.path.isdir(path1):
continue
for level2 in os.listdir(path1):
path2 = os.path.join(path1, level2)
if not os.path.isdir(path2):
continue
for level3 in os.listdir(path2):
path3 = os.path.join(path2, level3)
if not os.path.isdir(path3):
continue
# 取三级文件夹前10个字符作为日期基础名
date_name = get_base_name(level3)
if not date_name:
print(f"[跳过] 无法识别日期: {path3}")
continue
# 遍历四级文件夹,提取名称
extracted = []
for sub in os.listdir(path3):
sub_path = os.path.join(path3, sub)
if not os.path.isdir(sub_path):
continue
# 使用新的正则匹配四级文件夹名
sm = sub_pattern.match(sub)
if sm:
name = sm.group(1).strip()
# 过滤掉空字符串和纯数字,防止把类似 "01" 也提取进去
if name and not name.isdigit() and name not in extracted:
extracted.append(name)
if not extracted:
print(f"[跳过] 无有效四级文件夹: {path3}")
continue
# 合并提取到的名称
merged = "、".join(extracted)
new_name = f"{date_name} {merged}" # 日期 + 空格 + 合并名
new_path = os.path.join(path2, new_name)
# 如果新名字和老名字一样,就不处理了
if level3 == new_name:
continue
tasks.append((path3, new_path, level3, new_name))
print(f"原名: {level3}")
print(f"新名: {new_name}\n")
# ===== 第二步:确认后重命名 =====
if tasks:
# confirm = input(f"共 {len(tasks)} 个文件夹待重命名,输入 yes 执行:").strip().lower()
# if confirm == "yes":
# 两阶段重命名:先改成临时名,避免新旧名字冲突
temp_list = []
for i, (old, new, _, _) in enumerate(tasks):
temp = old + f"__tmp_{i}"
try:
os.rename(old, temp)
temp_list.append((temp, new))
except Exception as e:
print(f"失败 {old}: {e}")
for temp, new in temp_list:
try:
if os.path.exists(new):
print(f"[跳过] 目标已存在: {new}")
continue
os.rename(temp, new)
print(f"已重命名 → {os.path.basename(new)}")
except Exception as e:
print(f"失败 {temp}: {e}")
print("\n完成!")
else:
print("已取消。")
# else:
# print("没有需要处理的文件夹。")

同理制作20206-10-30文件夹



感悟:
由此,所有的照片整理程序代码都完成了,后续就是慢慢地修改四级文件夹的名字,转移照片,最后再跑程序,把三级文件夹名字添加合并汉字。

