我用 Python 写了 10 个自动化脚本,每天省出 2 小时:从文件整理到数据处理(附完整代码)
适合每天有大量重复性电脑操作的开发者、运营、内容创作者。
本文 10 个脚本全部可直接运行,覆盖文件处理、数据清洗、批量操作等高频场景。
背景:你的 2 小时去哪了
我统计过自己一天的"隐形时间消耗":
| 操作 | 每天耗时 | 频次 |
|---|---|---|
| 整理下载文件夹(按类型分类) | 10 分钟 | 2 次 |
| 批量重命名文件 | 5 分钟 | 1 次 |
| 从 Excel 提取数据写报告 | 20 分钟 | 1 次 |
| 批量压缩图片 | 10 分钟 | 1 次 |
| 检查网页内容是否更新 | 15 分钟 | 3 次 |
| 批量转换文件格式 | 10 分钟 | 1 次 |
| 汇总多个 CSV 文件 | 15 分钟 | 1 次 |
| 定时备份指定目录 | 5 分钟 | 1 次 |
| 批量替换文本内容 | 10 分钟 | 2 次 |
| 监控文件夹变化并通知 | 5 分钟 | 持续 |
加起来每天2 小时花在重复操作上。
下面 10 个 Python 脚本,把这些操作全部自动化了。
脚本 1:自动整理下载文件夹
按文件类型自动分类到子文件夹。
importosimportshutilfrompathlibimportPathdeforganize_downloads(download_dir):"""按文件类型整理下载文件夹"""# 类型→文件夹映射type_map={"图片":[".jpg",".jpeg",".png",".gif",".webp",".svg"],"文档":[".pdf",".doc",".docx",".txt",".md",".xlsx",".pptx"],"视频":[".mp4",".avi",".mkv",".mov"],"音频":[".mp3",".wav",".flac",".aac"],"压缩包":[".zip",".rar",".7z",".tar",".gz"],"代码":[".py",".js",".html",".css",".java",".go"],}download_path=Path(download_dir)moved=0forfileindownload_path.iterdir():iffile.is_file():ext=file.suffix.lower()forfolder,extensionsintype_map.items():ifextinextensions:target_dir=download_path/folder target_dir.mkdir(exist_ok=True)shutil.move(str(file),str(target_dir/file.name))moved+=1print(f"移动:{file.name}→{folder}/")breakprint(f"整理完成,共移动{moved}个文件")# 使用organize_downloads(r"C:\Users\Administrator\Downloads")脚本 2:批量重命名文件
按规则批量重命名,支持正则替换。
importosimportredefbatch_rename(directory,pattern,replacement):"""批量重命名文件:正则替换"""count=0forfilenameinos.listdir(directory):new_name=re.sub(pattern,replacement,filename)ifnew_name!=filename:old_path=os.path.join(directory,filename)new_path=os.path.join(directory,new_name)os.rename(old_path,new_path)print(f"重命名:{filename}→{new_name}")count+=1print(f"共重命名{count}个文件")# 示例:把文件名中的空格替换为下划线batch_rename(r"C:\files",r"\s+","_")# 示例:给所有 txt 文件加日期前缀batch_rename(r"C:\files",r"^(.+\.txt)$",r"2026_\1")脚本 3:批量压缩图片
把目录下所有图片压缩到指定大小以内。
fromPILimportImageimportosdefcompress_images(input_dir,output_dir,max_size_kb=500):"""批量压缩图片到指定大小"""os.makedirs(output_dir,exist_ok=True)count=0forfilenameinos.listdir(input_dir):ifnotfilename.lower().endswith(('.jpg','.jpeg','.png')):continueinput_path=os.path.join(input_dir,filename)output_path=os.path.join(output_dir,filename)img=Image.open(input_path)# 先缩小分辨率ifmax(img.size)>1920:ratio=1920/max(img.size)new_size=(int(img.width*ratio),int(img.height*ratio))img=img.resize(new_size,Image.LANCZOS)# 逐步降低质量直到目标大小forqualityinrange(85,10,-5):img.save(output_path,quality=quality,optimize=True)size_kb=os.path.getsize(output_path)/1024ifsize_kb<=max_size_kb:breakprint(f"压缩:{filename}→{size_kb:.0f}KB (质量={quality})")count+=1print(f"共压缩{count}张图片")# 使用compress_images("images_raw","images_compressed",max_size_kb=300)脚本 4:从 Excel 提取数据生成报告
importpandasaspddefgenerate_report(excel_path,output_path):"""从 Excel 读取数据,生成 Markdown 汇总报告"""df=pd.read_excel(excel_path)report=[]report.append(f"# 数据报告\n")report.append(f"数据来源:{excel_path}\n")report.append(f"总行数:{len(df)},总列数:{len(df.columns)}\n")# 数值列统计numeric_cols=df.select_dtypes(include='number').columnsiflen(numeric_cols)>0:report.append("## 数值统计\n")report.append("| 列名 | 均值 | 最大值 | 最小值 | 中位数 |\n")report.append("|------|------|--------|--------|--------|\n")forcolinnumeric_cols:report.append(f"|{col}|{df[col].mean():.2f}|{df[col].max()}|{df[col].min()}|{df[col].median():.2f}|\n")# 空值统计null_counts=df.isnull().sum()ifnull_counts.sum()>0:report.append("\n## 空值统计\n")forcol,countinnull_counts[null_counts>0].items():report.append(f"-{col}:{count}个空值\n")withopen(output_path,"w",encoding="utf-8")asf:f.writelines(report)print(f"报告已生成:{output_path}")# 使用generate_report("sales_data.xlsx","report.md")脚本 5:批量合并 CSV 文件
importpandasaspdimportglobdefmerge_csv(input_pattern,output_path):"""合并多个 CSV 文件"""files=glob.glob(input_pattern)dfs=[]forfileinfiles:df=pd.read_csv(file)df["_source"]=file# 记录来源dfs.append(df)print(f"读取:{file}({len(df)}行)")merged=pd.concat(dfs,ignore_index=True)merged.to_csv(output_path,index=False,encoding="utf-8-sig")print(f"合并完成:{len(files)}个文件 →{len(merged)}行 →{output_path}")# 使用merge_csv("data/*.csv","merged_data.csv")脚本 6:检查网页内容是否更新
importhashlibimportjsonimportrequestsfrompathlibimportPath CACHE_FILE="web_monitor_cache.json"defcheck_web_update(url):"""检查网页内容是否更新"""# 加载缓存cache={}ifPath(CACHE_FILE).exists():cache=json.loads(Path(CACHE_FILE).read_text(encoding="utf-8"))# 获取当前内容try:resp=requests.get(url,timeout=10)current_hash=hashlib.md5(resp.text.encode()).hexdigest()exceptExceptionase:print(f"获取失败:{url}-{e}")returnFalse# 对比old_hash=cache.get(url)ifold_hashisNone:cache[url]=current_hashprint(f"首次监控:{url}")elifold_hash!=current_hash:cache[url]=current_hashprint(f"✅ 内容更新:{url}")else:print(f"未变化:{url}")Path(CACHE_FILE).write_text(json.dumps(cache,ensure_ascii=False,indent=2),encoding="utf-8")returnold_hashisnotNoneandold_hash!=current_hash# 使用check_web_update("https://blog.csdn.net/nav/ai")脚本 7:批量文本替换
importosdefbatch_replace_text(directory,old_text,new_text,extensions=(".md",".txt",".py")):"""批量替换目录下所有文件中的指定文本"""count=0forroot,dirs,filesinos.walk(directory):forfilenameinfiles:ifnotfilename.endswith(extensions):continuefilepath=os.path.join(root,filename)content=open(filepath,encoding="utf-8").read()ifold_textincontent:new_content=content.replace(old_text,new_text)open(filepath,"w",encoding="utf-8").write(new_content)count+=1print(f"替换:{filepath}")print(f"共替换{count}个文件")# 使用batch_replace_text("articles","旧公司名","新公司名")脚本 8:定时备份指定目录
importshutilimportosfromdatetimeimportdatetimedefbackup_directory(source_dir,backup_root):"""备份目录,自动加日期后缀"""date_str=datetime.now().strftime("%Y%m%d_%H%M%S")source_name=os.path.basename(source_dir.rstrip("\\/"))backup_path=os.path.join(backup_root,f"{source_name}_{date_str}")shutil.copytree(source_dir,backup_path)print(f"备份完成:{source_dir}→{backup_path}")# 清理超过 7 天的旧备份importglob backups=sorted(glob.glob(os.path.join(backup_root,f"{source_name}_*")))whilelen(backups)>7:old=backups.pop(0)shutil.rmtree(old)print(f"清理旧备份:{old}")# 使用backup_directory(r"C:\projects\myproject",r"D:\backups")脚本 9:文件夹监控 + 自动处理
importtimeimportosdefwatch_folder(folder_path,callback,interval=5):"""监控文件夹变化,新增文件触发回调"""seen=set(os.listdir(folder_path))print(f"开始监控:{folder_path}")whileTrue:time.sleep(interval)current=set(os.listdir(folder_path))new_files=current-seenforfilenameinnew_files:filepath=os.path.join(folder_path,filename)ifos.path.isfile(filepath):print(f"发现新文件:{filename}")callback(filepath)seen=current# 使用:新文件自动整理defauto_process(filepath):iffilepath.endswith(".md"):print(f" → 检测到 Markdown 文件,自动处理")eliffilepath.endswith((".jpg",".png")):print(f" → 检测到图片,自动压缩")watch_folder(r"C:\watch_folder",auto_process,interval=3)脚本 10:批量转换文件编码
importosdefconvert_encoding(input_dir,from_enc="gbk",to_enc="utf-8"):"""批量转换文件编码"""count=0forroot,dirs,filesinos.walk(input_dir):forfilenameinfiles:ifnotfilename.endswith((".txt",".csv",".md",".py")):continuefilepath=os.path.join(root,filename)try:content=open(filepath,encoding=from_enc).read()open(filepath,"w",encoding=to_enc).write(content)count+=1print(f"转换:{filename}({from_enc}→{to_enc})")exceptUnicodeDecodeError:print(f"跳过:{filename}(编码不匹配)")print(f"共转换{count}个文件")# 使用convert_encoding("old_files",from_enc="gbk",to_enc="utf-8")踩坑记录
坑 1:shutil.move 遇到同名文件
症状:移动文件时如果目标目录已有同名文件,直接报错。
解决:移动前检查是否存在,存在则加序号后缀。
iftarget.exists():stem=target.stem suffix=target.suffix i=1whiletarget.exists():target=target_dir/f"{stem}_{i}{suffix}"i+=1坑 2:正则替换文件名特殊字符
症状:文件名含[]()等正则特殊字符,替换结果不对。
解决:用re.escape()转义特殊字符。
坑 3:Excel 读取中文列名乱码
症状:pd.read_excel()读出来的中文列名是乱码。
解决:指定编码encoding="utf-8-sig",或者用pd.read_excel()时不需要指定编码(Excel 格式自带编码信息)。
坑 4:文件监控脚本 CPU 占用高
症状:watch_folder脚本跑一会儿 CPU 就飙到 10%。
原因:interval=1轮询太频繁。
解决:把 interval 设到 5 秒以上,或者用watchdog库的事件驱动模式。
坑 5:备份脚本磁盘空间不足
症状:备份几次后磁盘满了。
解决:备份前检查剩余空间,不足时清理最旧的备份。
总结
3 条经验:
先统计再自动化。花 1 天记录自己的重复操作,找到最耗时的环节再写脚本,别什么都自动化。
脚本 > 手动 > 工具。简单的文件操作用 Python 脚本比装软件更轻量,也不会有软件收费或兼容性问题。
加日志和异常处理。生产用的脚本一定要加 try-except 和 print 日志,出问题时才能排查。
你日常有哪些重复操作想自动化?评论区聊聊,说不定下篇就写你提的需求。