Python自动化脚本实战:10个代码搞定文件办公与系统监控
发布时间:2026/10/1 17:21:35来源:尧图网络
做Python开发这几年少说也写了上百个脚本真正让我觉得“这玩意儿没白学”的反而是那些不起眼的小工具自动整理桌面文件、批量改文件名、定时给你弹个喝水提醒、爬个网页监控价格变化。它们不复杂几百行以内就能搞定却实实在在把我从重复点击里捞了出来。这篇文章就是冲着“Python自动化脚本”这个方向来的。我挑出了日常使用频率最高、最具备通用性的10个脚本按文件处理、办公数据、网络抓取、系统运维四个场景拆开讲。每个脚本都附上完整代码和我在真实环境里用到的细节说明包括为什么这么写、容易踩哪些坑。看完你就能照着抄改改路径和条件直接变成你自己的工具。无论你是刚入门Python的小白还是写了几年代码但不想重复造轮子的人这套清单都能帮你省下不少事。干活的思路比背语法重要下面直接进正题。1. 动手之前环境准备与脚本设计思路1.1 安装Python与依赖库先解决基础环境。多数Linux发行版和macOS自带PythonWindows则需要到官网下载安装包安装时记得勾选“Add Python to PATH”。装好后在终端验证python --version如果显示版本号就说明环境通了。接下来按脚本需求安装第三方库我用到的核心库有pip install requests beautifulsoup4 openpyxl pandas pypdf psutil schedule plyer这里做个分工说明requests负责网络请求openpyxl和pandas负责Excel读写pypdf处理PDFpsutil获取系统状态schedule做定时调度plyer发桌面通知。装完就能覆盖本文全部脚本。1.2 我写自动化脚本的三条铁律写了这么多脚本我总结出三个习惯能帮你少走很多弯路第一脚本必须能反复执行。很多新手写完脚本第二次跑就报错因为没考虑到目标文件夹已经存在、文件名称冲突、数据重复等问题。所以我写的每个脚本开头都会做“幂等处理”——目录存在就跳过文件冲突就加时间戳数据重复就覆盖。第二路径全部用Path对象。Python里处理路径尽量用pathlib库的Path而不是手动拼字符串。Windows下反斜杠转义问题、Linux下斜杠问题Path对象全都自动处理了代码换到任何系统都能跑。第三任何删除操作都要先滤一遍。涉及删除文件、改写文件之类的步骤我会先把要处理的对象打印出来确认无误再真正执行。批量场景下一次误操作恢复的成本实在太高。这三条不是学术建议是从真实事故里总结出来的。后面每个脚本里你都会看到这些原则的影子。2. 文件与目录自动化三招解决日常整理2.1 脚本一桌面文件一键分类大多数人桌面都乱成灾区截图和文档混在一起压缩包和安装包到处堆。手动整理一次能累个半死还容易手滑把文件挪错。这个脚本直接按扩展名给所有文件分类归档。import shutil import time from pathlib import Path desktop Path.home() / Desktop target_root Path.home() / Desktop / 自动整理 ext_map { 图片: [.jpg, .jpeg, .png, .gif, .bmp, .webp], 文档: [.doc, .docx, .pdf, .txt, .md, .xls, .xlsx, .ppt, .pptx], 压缩包: [.zip, .rar, .7z, .tar, .gz], 程序: [.exe, .msi, .sh, .bat], 音频视频: [.mp3, .mp4, .wav, .flac, .avi, .mkv], } for file in desktop.iterdir(): if file.is_file() and not file.name.startswith(.): category 其他 for name, exts in ext_map.items(): if file.suffix.lower() in exts: category name break target_dir target_root / category target_dir.mkdir(parentsTrue, exist_okTrue) dest target_dir / file.name # 处理同名文件加时间戳避免覆盖 if dest.exists(): dest target_dir / f{file.stem}_{int(time.time())}{file.suffix} shutil.move(str(file), str(dest)) print(f已移动 {file.name} - {category})这个脚本的关键点有两处。一是iterdir()只遍历顶层文件不会连文件夹一起搬走避免了误伤。二是同名文件冲突时自动在文件名后加时间戳确保不覆盖原有内容。我在实际使用中还会再加一步先把桌面路径改成自己常用的工作目录比如“下载”文件夹把脚本跑一遍效果一模一样。如果文件夹里文件特别多建议先跑一段只打印不移动的“演练版”确认分类规则没问题再真搬。2.2 脚本二批量重命名不再手抖给一组文件加上规范前缀、序号或日期是照片、素材、报表管理的日常需求。手动逐个改名效率低且容易出错脚本处理反而更快更稳。from pathlib import Path from datetime import datetime folder Path(rD:\素材) date_str datetime.now().strftime(%Y%m%d) for i, file in enumerate(folder.iterdir(), start1): if file.is_file() and not file.name.startswith(.): new_name f{date_str}_{i:03d}_{file.name} file.rename(file.with_name(new_name)) print(f{file.name} - {new_name})代码里用enumerate(..., start1)生成从01开始的序号固定3位数字。日期戳直接取自当前日期适合按天归集素材的场景。如果要做更复杂的重命名比如从文件名中提取日期、编号然后重新组合配合正则表达式会更强大。比如老文件格式是“20240901_001_原始名.jpg”想统一改成“2024-09-01-001.jpg”可以做一次替换匹配。这类用re模块处理规则灵活得多。别在大量文件上直接跑没有预览的脚本。我习惯在rename之前把新旧名字的对应关系写入一个文本确认无误再执行。改名操作不可逆这是血泪教训。2.3 脚本三增量备份资料永不丢失手动备份文件最烦的是什么全量拷贝太浪费时间又经常忘。用脚本做增量备份只复制新增或修改过的文件又快又省空间。import shutil from pathlib import Path from datetime import datetime src Path(rC:\Users\me\Documents) dst_root Path(rD:\Backup) today datetime.now().strftime(%Y%m%d) dst dst_root / today backup_count 0 for file in src.rglob(*): if file.is_file(): rel_path file.relative_to(src) target dst / rel_path # 目标文件不存在或源文件比目标文件新才复制 if not target.exists() or file.stat().st_mtime target.stat().st_mtime: target.parent.mkdir(parentsTrue, exist_okTrue) shutil.copy2(file, target) backup_count 1 print(f本次备份 {backup_count} 个文件)rglob(*)递归遍历所有子目录shutil.copy2会保留文件的修改时间等元信息。比较源文件和目标文件的mtime只有“源文件更新”时才执行复制这就是增量的逻辑。我用这个脚本每晚备份工作文档配合计划任务自动运行已经跑了一年多。要注意的是这个方案只做增量不做删除同步——如果源目录里删了文件备份里不会自动删除。如果需要“镜像同步”得用filecmp比较后删除多余文件但删除操作要谨慎建议保留一个暂存区。3. 办公数据自动化Excel与PDF的折腾终结者3.1 脚本四多个Excel一键合并这应该是办公场景里被问最多的问题了。每月各部门发来几十个工作簿格式一样、数据不同手动复制粘贴到怀疑人生。用pandas三行代码搞定。import pandas as pd from pathlib import Path files list(Path(rD:\Monthly).glob(*.xlsx)) df_list [] for f in files: df pd.read_excel(f) df[来源文件] f.name # 标记数据来源 df_list.append(df) merged pd.concat(df_list, ignore_indexTrue) merged.to_excel(merged.xlsx, indexFalse) print(f已合并 {len(files)} 个文件共 {len(merged)} 行数据)这个脚本适用于“所有表格列结构一致”的情况。如果列结构不完全一致concat会用NaN填充缺失列也能勉强合并。常见坑点有两个一是某些表格第一行是标题而不是表头读取时要设置header1二是某些单元格是日期格式读取后变成时间戳可以用converters参数指定列类型。跑通之后每个月把文件丢进指定目录双击脚本几秒钟就得到合并结果。这种简单的重复劳动脚本是完美替代品。3.2 脚本五PDF元数据快速提取PDF的处理一直是办公自动化的痛点。平时需要从大量PDF里提取标题、页数和首页内容手动打开几十个文件再一一记下来实在痛苦。pypdf库能帮上忙。from pypdf import PdfReader from pathlib import Path for pdf_path in Path(rE:\Docs).glob(*.pdf): reader PdfReader(pdf_path) meta reader.metadata pages len(reader.pages) # 提取第一页文本的前100个字符作为预览 preview if reader.pages: preview reader.pages[0].extract_text()[:100] print(f文件: {pdf_path.name}) print(f 页数: {pages}) print(f 标题: {meta.title if meta and meta.title else 无}) print(f 预览: {preview.replace(chr(10), )})注意pypdf是PyPDF2的官方继任者新代码建议直接pip install pypdf。它的extract_text()在文字型PDF上表现不错但扫描版PDF提取出来是乱码或空白那种情况需要OCR工具不是pypdf能解决的。用这个脚本我可以把几百份说明书的关键信息在10秒内集中导出来比一个个打开效率提升太多。往深了做还能配合合并功能把PDF按页数拆分或者把文件按标题重新分组。3.3 脚本六自动生成带格式的Excel报表数据处理只是第一步日常工作还要求“把结果做成规范的报表”该有标题加粗、底色填充、边框线一眼看去专业。openpyxl可以控制这些格式细节。from openpyxl import Workbook from openpyxl.styles import Font, PatternFill, Alignment, Border, Side wb Workbook() ws wb.active ws.title 月度汇总 # 填入数据 headers [月份, 销售额, 利润, 备注] rows [ [2024-01, 12000, 3000, 正常], [2024-02, 15000, 4000, 春节促销], [2024-03, 11000, 2500, 淡季], ] ws.append(headers) for row in rows: ws.append(row) # 表头样式 header_font Font(boldTrue, colorFFFFFF) header_fill PatternFill(solid, fgColor4472C4) thin Side(stylethin, color000000) border Border(leftthin, rightthin, topthin, bottomthin) for cell in ws[1]: cell.font header_font cell.fill header_fill cell.alignment Alignment(horizontalcenter, verticalcenter) cell.border border # 为数据区域统一加边框 for row in ws.iter_rows(min_row1, max_col4, max_rowws.max_row): for cell in row: cell.border border # 设置列宽 ws.column_dimensions[A].width 12 ws.column_dimensions[B].width 12 ws.column_dimensions[C].width 12 ws.column_dimensions[D].width 20 ws.freeze_panes A2 # 冻结表头行 wb.save(monthly_report.xlsx) print(报表已生成)代码里freeze_panes A2是个实用的小细节设置了之后表头行固定不动往下滚动数据时也能看到列名。样式代码看着多但它是模板化的一次性写好后面所有报表都能复用。很多人不知道openpyxl还可以加载已有Excel模板再修改而不是从空白簿开始。如果你的公司有固定格式报表用load_workbook(template.xlsx)加载模板填入数据重新保存样式就不会丢。4. 网络与信息获取让脚本帮你“盯梢”4.1 脚本七网页价格监控与提醒盯商品价格、盯着某页面内容更新这些靠人眼刷新最浪费生命。写一个轮询脚本定时抓取网页内容满足条件就提醒。import requests import re import time URL https://example.com/product/123 TARGET_PRICE 100.0 CHECK_INTERVAL 3600 # 秒 def get_price(url): headers {User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)} resp requests.get(url, headersheaders, timeout10) html resp.text # 根据实际页面结构调整匹配规则 match re.search(r(\d\.\d{2}), html) return float(match.group(1)) if match else None while True: try: price get_price(URL) if price and price TARGET_PRICE: print(f价格到了当前 {price} 元可以下单了。) # 这里可以插入发送邮件、企业微信机器人的代码 break else: print(f检查完成当前价格 {price} 元) except Exception as e: print(f请求出错: {e}) time.sleep(CHECK_INTERVAL)这里有一个重要的原则爬虫不是非法工具最关键的是遵守规则。我只建议你爬取站点公开展示、无需登录的数据同时控制访问频率至少要给服务器留几秒缓冲。requests请求之间加随机等待、带上常见User-Agent既降低被封风险也是对其他站点的尊重。正则匹配价格只是最简方式。如果页面结构复杂建议换BeautifulSoup按class定位元素稳定很多。如果对方有反爬措施导致频繁403别硬刚优先改成人工间歇性查看或者看看对方有没有官方API。4.2 脚本八批量下载文件告别逐个右键下载一批素材、备份一组附件、批量拉取报表手动一个个右键另存为能点到手酸。用requests配合流式下载几行代码解决。import requests from pathlib import Path urls [ https://example.com/files/report_01.pdf, https://example.com/files/report_02.pdf, https://example.com/files/report_03.pdf, ] out_dir Path(downloads) out_dir.mkdir(exist_okTrue) for url in urls: name url.split(/)[-1] resp requests.get(url, streamTrue, timeout30) if resp.status_code 200: file_path out_dir / name with open(file_path, wb) as f: for chunk in resp.iter_content(chunk_size8192): f.write(chunk) print(f已下载 {name}) else: print(f下载失败: {url} 状态码 {resp.status_code})核心细节在streamTrue。如果文件很大不设置stream的话requests会一次性把整个文件加载进内存下载2GB文件内存直接爆掉。用iter_content按块写入磁盘内存占用始终很小。实际工程里我会把urls列表改成从一个txt文件读取每行一个链接这样下载任务清单可以随时增删不需要改代码。再进一步还可以加超时重试和断点续传但那种复杂度对多数场景没必要。4.3 脚本九定时任务与桌面弹窗提醒很多人开着电脑工作一坐就是半天想喝水、想站起来活动全靠自觉。写个桌面提醒脚本每小时弹一条通知简单粗暴。import schedule import time from plyer import notification def remind_stand(): notification.notify( title休息一下, message已经工作一小时了起来活动活动看看远处。, timeout10 ) def remind_water(): notification.notify( title喝水提醒, message喝口水别等到渴了才喝。, timeout10 ) schedule.every(1).hour.do(remind_stand) schedule.every(30).minutes.do(remind_water) print(提醒脚本已启动按 CtrlC 退出) while True: schedule.run_pending() time.sleep(1)schedule是一个轻量定时库API很友好特别适合这种脚本内循环。但要注意它只在脚本运行期间生效一旦电脑重启、脚本没启动提醒就断了。所以更可靠的做法是把脚本注册成系统计划任务下面的5.2会讲。把提醒间隔改成工作时段、加入更多自定义内容相当于一个迷你版的“时间管理助手”。5. 系统运维日常把监控交给脚本5.1 脚本十CPU内存磁盘监控与日志清理电脑卡顿、磁盘飘红往往是内存或磁盘长期高负载导致的。与其等出了问题再救急不如写个监控脚本定期记录系统状态超过阈值时留下警告日志。import psutil import logging from datetime import datetime log_file sys_monitor.log logging.basicConfig( filenamelog_file, levellogging.INFO, format%(asctime)s [%(levelname)s] %(message)s, encodingutf-8 ) cpu psutil.cpu_percent(interval1) mem psutil.virtual_memory() disk psutil.disk_usage(C:\\) if cpu 80 or mem.percent 85 or disk.percent 90: logging.warning(f高负载: CPU {cpu}% | 内存 {mem.percent}% | 磁盘 {disk.percent}%) else: logging.info(f正常: CPU {cpu}% | 内存 {mem.percent}% | 磁盘 {disk.percent}%)配合清理临时文件的需求可以再加一段清理7天前临时文件的逻辑import os import tempfile import time temp_dir tempfile.gettempdir() old_threshold time.time() - 7 * 86400 cleaned 0 for root, dirs, files in os.walk(temp_dir): for f in files: path os.path.join(root, f) try: if os.path.getmtime(path) old_threshold: os.remove(path) cleaned 1 except PermissionError: pass print(f清理临时文件 {cleaned} 个)清理临时目录要格外小心。首先只清理超过7天的文件给正在运行的程序留缓冲其次要单独试运行确认没有删掉被占用或正在使用的文件最后最好先做一次“只统计不清除”的演练。psutil是Python里检查系统资源的利器跨平台支持Windows、Linux、macOS。它可以拿到的指标非常多CPU核心数、进程列表、网络流量、传感器温度都能做成周期性报表。5.2 让脚本彻底跑起来Windows任务计划与Linux crontab脚本写好了但你不能天天手动打开终端跑。真正实现“解放双手”的最后一环是把脚本挂到系统调度器上。Windows下打开“任务计划程序”新建任务触发器设为“每天”操作里选择“启动程序”程序填python参数填脚本的完整路径。这样到点系统自动执行执行日志可以定向到文本文件故障时好排查。Linux和macOS下用crontab一行搞定。终端执行crontab -e添加0 9 * * * python /home/user/scripts/daily_clean.py /home/user/scripts/run.log 21这条意思是每天9点整执行脚本同时把输出写入日志。crontab的五段格式分别是分、时、日、月、周0 9 * * *就是每天9点。这里有一个很关键的运维思维调度器只负责启动脚本脚本本身是否成功要由日志来审计。所以每个脚本里加上日志输出配合run.log才能及时发现问题。5.3 脚本打包与部署的进阶思路如果脚本要放到一台没有Python环境的电脑上运行比如公司服务器或同事的机器可以用PyInstaller打包成独立的exe。pip install pyinstaller pyinstaller -F -w daily_clean.py-F表示打包成单文件-w表示运行时不显示控制台窗口。执行完在dist目录下会生成同名exe拷到任何Windows机器都能直接跑无需预装Python。打包执行后原有的路径和日志位置会变化所以脚本里尽量不要用相对路径统一用Path(__file__).parent获取脚本所在目录保证打包后文件路径依然正确。6. 踩坑记录与调试技巧6.1 我踩过的5个典型坑第一中文路径报错。Windows中文用户名导致路径里有中文某些库处理不了。解决方法是文件操作统一用pathlib写入文件时指定encodingutf-8。第二Excel读取后日期变了。pandas读Excel会把日期识别成Timestamp写入数据库时会整出幺蛾子。解决办法是读取时指定parse_dates或者干脆用converters把该列转成字符串。第三requests请求被拒。爬取部分网站会出现403大多是User-Agent太朴素。加上浏览器UA字符串后大概率能解决再不行就加请求间隔。第四乱删文件的灾后重建。我早期写自动清理脚本时路径拼接错了把正常文件都扫进了删除列表。从此以后凡是涉及删除的重构脚本我强制要求先打印“将要删除的文件清单”人工确认一次再真正执行。第五脚本定时任务没生效。Windows任务计划里填了相对路径或者路径里有空格会导致程序找不到文件。解决方式是程序路径和参数都用英文双引号包裹日志强制输出绝对路径。6.2 踩坑速查表现象常见原因处理办法ModuleNotFoundError依赖库未装pip install对应包名确认解释器路径正确UnicodeDecodeError文件编码不是UTF-8open时指定encodingutf-8或gbkPermissionError文件被占用或权限不足以管理员运行或跳过被占用的文件FileExistsError目标文件已存在写入前判断存在性加时间戳或自动改名中文乱码控制台编码问题脚本开头加# -*- coding: utf-8 -*-Windows下可用chcp 65001定时任务无日志脚本异常退出崩溃信息重定向到日志文件用try-except捕获全局异常爬虫抓不到数据页面为动态渲染检查响应文本里是否有目标字符改用浏览器渲染或找接口URL6.3 让脚本更好用的小习惯最后分享几个让我自己受益很久的习惯。第一个是为每个脚本添加if __name__ __main__:入口声明把主逻辑放进函数里。这样脚本既能直接运行也能被其他脚本import调用形成自己的工具库。第二个是用argparse接收参数不要把路径写死在代码里。比如桌面整理脚本可以接收--dir参数import argparse parser argparse.ArgumentParser(description文件整理脚本) parser.add_argument(--dir, defaultstr(Path.home() / Desktop), help要整理的目录) args parser.parse_args() target_dir Path(args.dir)这样做的好处是脚本和具体场景解耦换个目录、换组文件都不需要改源码。第三个是把所有脚本集中放进同一个scripts目录并写一个README文档记录每个脚本的用途、依赖、调度时间。半年后再回来看你一定会感谢当时的自己。我在实际使用中发现这些脚本单拎出来每一个都朴素得不像“技术”但把它们串成一个自动化工具箱之后节省的是每天半小时到一小时的重复劳动。这半小时不用来摸鱼用来做更有价值的事才是自动化真正的意义。
网站建设高端定制企业官网