自动化与爬虫 — 把重复交给脚本,把策略交给 AI
自动化与爬虫 — 把重复交给脚本,把策略交给 AI
这一章讲什么: 开发者的一天大量漏在小事里:改文件名、清下载夹、从长文档抠几行、 每周发同样的邮件。这一章教你把这些变成不用人盯的脚本,并第一次让脚本 按点自己跑。工具只用标准库加三四个第三方库;AI 的角色从「写码主力」 变成「策略顾问」——你把现状喂给它,它帮你设计怎么自动化。 读完你会得到一个判断:什么任务值得自动化,以及第一版脚本该从哪一行写起。
1. 这一章讲什么
前面四章都在「学」:学读码、学问 AI、学调试。这一章开始「省」: 把重复劳动从手上拿掉。书里给这一章的动机很直白: 开发者的时间消失在各种「永远进不了绩效回顾」的小事里——改文件名、清乱文本、挪日志、 从长文档抠几行、发周报、解析别人拍胸脯说「已经结构化」的数据1。 这些事单个看都小,合起来偷走你的注意力、打断心流、把一下午拉长2。
而 Python 天生就是为这种世界造的。 配合前两章的两样手艺(拆步骤、说清楚), 它就成了「你多出来的一双手」3。这一章在全书链条里是第一个真正的项目章: 从这一章起,每章结束你手里都多一个能日常使用的工具。
2. 顶层全景:四个库 + 两个场景 + 一个总原则
四个库各管一件事:
os = 手:看文件夹、查存在、批量改名、删文件
shutil = 叉车:复制、移动、整目录备份、打包压缩
datetime = 钟:时间戳文件名、算文件年龄、按星期几条件执行
schedule = 闹钟:让脚本按点自己跑
│
▼
场景一:文件管理(分类、改名、清理) 场景二:文本处理(提取、清洗)
场景三:网页抓取(requests 取页 + BeautifulSoup 解析,含分页)
│
▼
总原则:发现自己在重复 → 「能不能让 Python 和 ChatGPT 替我做?」
图说:上面四个库是零件,中间三个场景是装法,最下面那行是这一章想刻进习惯的反应。3. 核心原理
3.1 总原则:自动化的第一推动力是「烦」,不是「懂」
书里有一句反拖延的提醒:别等「全懂了」才开始——学自动化最快的方式就是今天自动化一件小事4。 而发现值得自动化的事,只需要一条反射:每当你发现自己在重复, 第一个念头应该是「能不能让 Python 和 ChatGPT 把这个从我盘子里拿走?」5
书里还立了两条贯穿全章的规矩:
3.2 os:操作系统的大门
os 是 Python 里「摸文件系统」的标准库——列目录、查路径存在与否、建多层文件夹、删文件、 批量改名、跨操作系统安全地拼路径8。书里的比喻:如果 Python 是一个人,os 就是他的手9。
自动化之前,先看见。 书里教的第一步不是写,是「侦察」:用 pathlib 的 Path.home() / "Downloads"
定位下载文件夹,iterdir() 列出里面所有条目并打印。把这份清单贴给 ChatGPT,
问:「这是我下载夹里的文件。帮我设计一个用 os 模块自动整理它们的分类策略。」
AI 会从文件名里看出你没注意到的模式——图片、发票、安装包、讲义、视频——给出分类方案10。
书里把这一手点得很透:机器看见原始数据,ChatGPT 帮你思考它11。
批量改名主线例子(第一圈)。 书里的练习:给下载夹里的文件按 file_1.jpg、file_2.pdf 编号改名:
import os
folder = "/Users/yourname/Downloads"
for index, file in enumerate(os.listdir(folder), start=1):
base, ext = os.path.splitext(file) # 拆成「主名.扩展名」两半
new_name = f"file_{index}{ext}" # 新名 = 编号 + 原扩展名
os.rename(os.path.join(folder, file), os.path.join(folder, new_name))三个新词当场讲掉:enumerate(..., start=1) 是「边遍历边给序号,从 1 开始」;
os.path.splitext 把文件名在最后一个点处切开(扩展名留住,改名才不改丢类型);
os.path.join 用操作系统认可的分隔符拼路径——Windows 是反斜杠、macOS/Linux 是正斜杠,
交给它就两边都对12。跑完再给 AI 提一条精炼:「改成只改 .jpg、保留创建日期元数据(文件自带的创建时间等附属信息)」13——
这就是迭代,第三章的套路原样复用。
3.3 shutil:需要力气时的叉车
os 管「单个文件的日常操作」;shutil 管「批量与整棵目录树」:复制文件、整目录复制、 移动、删整目录、自动打 zip/tar.gz 压缩包14。书里的比喻:os 是手,shutil 是叉车15。
主线例子(第二圈):每日备份脚本。 需求:把项目目录每天备份一份,带时间戳:
from pathlib import Path
import shutil
from datetime import datetime
source = Path.home() / "my_project"
timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M")
destination = Path.home() / "Backups" / f"my_project_{timestamp}"
shutil.copytree(source, destination) # 整棵目录树复制过去
print("Backup completed successfully.")copytree 一次复制整个目录(包括所有子目录);strftime("%Y-%m-%d_%H-%M") 把时间格式化成
2025-11-25_08-30 这样的字符串,保证每次备份文件夹名唯一、按字典序即按时间序16。
跑通之后,书里照例让你继续问:「扩展这个备份脚本:自动删除 10 天前的备份,
并把昨天的备份压成 zip。」AI 会给出带安全检查的「生产级」版本——
安全检查常常是你没想到、而它主动补上的那一层17。
3.4 datetime:让脚本懂时间
想让脚本「今天和昨天行为不同」「周末和工作日不同」,就需要 datetime。
书里的四大用途:生成唯一文件名(backup_2025-11-25.zip)、算文件年龄、
按条件排期(「只在工作日跑」)、给日志加日期18。
日志——自动化的脉搏。 书里的最小例子:
import datetime
today = datetime.date.today()
filename = f"system_log_{today}.txt"
with open(filename, "a") as log:
log.write(f"{datetime.datetime.now()} - Daily check completed.\n")每天追加一行。书里的比喻:日志是自动化的心跳,每次脚本运行都给你一个稳定的脉搏19。 照例可升级:「把它改成每周归档、删除 90 天前日志的轮转日志(rotating log)」20。
3.5 schedule:让脚本自己跑
schedule 是一个第三方库,让 Python 脚本按时刻表触发函数——没有它, 「自动化」只是「把手动运行换个说法」21。书里的定场诗是: 电脑是一堆小而可预测的仪式;人类不擅长仪式(会烦、会忘、会分心); Python 没有自尊也没有抱怨,同一任务跑一千次也乐意22。
安装一行:pip install schedule。最小骨架(每晚 23:00 清理临时文件):
import schedule, time, os
def clean_temp():
folder = "/Users/yourname/Downloads"
for f in os.listdir(folder):
if f.endswith(".tmp"):
os.remove(os.path.join(folder, f))
print("Removed:", f)
schedule.every().day.at("23:00").do(clean_temp)
while True: # 脚本常驻,每秒看一次有没有到点的任务
schedule.run_pending()
time.sleep(1)三个关键点:schedule.every().day.at("23:00").do(函数) 注册任务;
run_pending() 检查到点没;time.sleep(1) 让循环每秒醒一次,不空转烧 CPU。
升级照例交给 AI:「改成清理后给我发一条 Telegram 消息,并且周日跳过」23。
排期只有三条路(书里给了全景):手动跑(不算自动化)、schedule(学习者最容易)、 操作系统级排期(macOS/Linux 的 cron,Windows 的任务计划程序)24。
补充(不在书里,来自通用知识): schedule 的方案有一个硬限制—— 脚本必须在某个终端里一直开着;电脑关机或终端关闭,定时任务就停。 要「无人值守」,最终还是得上 cron/任务计划程序;书里把这条路标出来但没走, 这是本章与生产环境之间最远的一步。
3.6 主线例子(第三圈):四库合体的「早间巡检」
把上面四个零件装进一个真实工作流:每天早 8 点,自动完成——扫描下载夹、按类型分类、 带时间戳备份、写日志、清理临时文件25。骨架:
DOWNLOADS = Path.home() / "Downloads"
BACKUP_ROOT = Path.home() / "Backups"
def morning_audit():
now = datetime.now()
# 1. 按扩展名分类
for item in DOWNLOADS.iterdir():
if not item.is_file():
continue
_, ext = item.stem, item.suffix.lower()
category = "others"
if ext in [".jpg", ".png"]: category = "images"
elif ext in [".pdf", ".docx"]: category = "documents"
elif ext in [".mp4", ".mov"]: category = "videos"
dest_dir = DOWNLOADS / category
dest_dir.mkdir(exist_ok=True) # 目录在就跳过,不在就建
shutil.move(str(item), dest_dir / item.name)
# 2. 整夹备份
backup_path = BACKUP_ROOT / f"backup_{now:%Y%m%d_%H%M}"
shutil.copytree(DOWNLOADS, backup_path)
# 3. 写日志
log_file = Path.cwd() / f"log_{now:%Y-%m-%d}.txt"
with log_file.open("a") as log:
log.write(f"{now}: Audit completed.\n")
print("Morning audit done.")
schedule.every().day.at("08:00").do(morning_audit)
while True:
schedule.run_pending()
time.sleep(1)细节里藏着两个易错点,书里都点到了:mkdir(exist_ok=True) 是幂等写法
(「目录已存在不报错」——幂等 idempotent 的意思是同一脚本重复跑不会产生意外副作用,
本章 Key Terms 之一26);item.stem, item.suffix 拆主名与扩展名,后缀统一小写再比对,
.JPG 和 .jpg 才不会漏网。跑通后继续问 AI:「加上:压缩旧备份、发报告邮件、跳过大于 1GB 的文件」27。
3.7 场景二:文本处理——提取与清洗
第二个场景处理的是「人读的文本」。工具全是标准库:open() 读写文件、
re 正则表达式(描述字符模式的迷你语言,比如「邮箱 = 一串字符 + @ + 域名 + . + 后缀」)、
.split()/.replace() 快速清理、json 结构化数据、csv 表格28。
提取主线例子:从日志里抠邮箱。 建一个 logs.txt 混各种内容,提示:
「写脚本从 logs.txt 提取所有邮箱地址,写进 emails.csv;只用标准库。」拿到的核心两行:
pattern = r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"
emails = re.findall(pattern, text)这个 pattern(模式串)不用背,能看懂大意即可: @ 前允许字母数字和 ._%+- 这些符号;
@ 后是域名;\. 是转义的点;[a-zA-Z]{2,} 要求顶级域名至少两个字母(所以 .co 行、.com 行都中,
单字符的 .c 不中)29。提取完照例升级:去重、按字母排序、计数30。
清洗:建流水线,不是一次性脚本。 提示:「帮我清洗文本文件:去 HTML 标签、转小写、 合并连续空格。」拿到基线后逐条加码:去数字、只留字母、去停用词(stopword,英语里 the/and/is 这类高频但少含义的词——本章 NLP 的伏笔,第七章会系统讲)、输出摘要。 书里强调:每一小改都教你一点文本自动化的新东西31。
3.8 场景三:网页抓取——互联网变成数据牧场
书里给抓网页的定义很有画面感:某个时刻,互联网从你「浏览的地方」变成你「收割的地方」—— 你不再手动点页面,你的脚本安静地穿过网站,挑出你要的确切信息32。 这件事的行话叫 web scraping(网页抓取/爬虫)。
两把工具,分工明确:
- requests = 代码里的浏览器:负责把网页的 HTML 取回来;
- BeautifulSoup = 手术刀:负责把 HTML 切成片——标题、价格、链接、日期33。
安装:pip install requests beautifulsoup4。书里提醒:永远显式安装,别假设环境里有34。
抓取提示的模板(本章最有复用价值的一段)。 写任何抓取脚本前,先给 AI 这样一条 CCG:
「用 requests 和 BeautifulSoup 写脚本抓 [URL]。提取:[条目1]、[条目2]、[条目3]。 结果以字典列表返回。必须:带解释性注释;缺字段要优雅处理;用 try/except; 不引额外依赖;在 VS Code 里能跑;假定用户会自己 pip install requests beautifulsoup4。 只返回干净可读的代码,不要多余文字。」35
书里说这个提示「紧凑但全面」——注意它依然是 CCG:背景(抓什么)、约束(依赖、错误处理、行数风格)、 目标(字典列表)。
例一:抓博客标题。 目标页 blog.python.org,提取每篇文章的标题与链接:
response = requests.get(url)
time.sleep(1) # 礼貌停顿
soup = BeautifulSoup(response.text, "html.parser")
posts = []
for item in soup.select(".post-title a"): # CSS 选择器:选中所有 class=post-title 里的 <a>
posts.append({
"title": item.get_text(strip=True),
"link": item["href"]
})选择器(selector) 是这里唯一的新词:CSS 选择器是「按标签名/class/ id 定位 HTML 元素」的
模式串,.post-title a 读作「class 叫 post-title 的元素内部的所有 a 标签」36。
time.sleep(1) 是礼貌停顿——连续猛请求会把对方服务器打烦37。
例二:抓电商价格。 books.toscrape.com(一个专门练爬虫的演示站),提取书名、价格、库存状态:
select(".product_pod") 拿到每个商品卡片,卡片内 select_one(".price_color") 取单价、
select_one(".instock.availability") 取库存38。跑通后一句「转成 CSV 导出」,
AI 就优雅地把结果接到 csv 模块39。
例三:分页——真实世界的常态。 多数网站一页装不下,要「下一页」翻过去。 quotes.toscrape.com 的写法:
base_url = "https://quotes.toscrape.com"
page_url = "/page/1/"
quotes = []
while page_url: # 只要还有下一页就继续
response = requests.get(base_url + page_url)
soup = BeautifulSoup(response.text, "html.parser")
for q in soup.select(".quote"):
quotes.append({
"text": q.select_one(".text").get_text(strip=True),
"author": q.select_one(".author").get_text(strip=True),
"tags": [t.get_text(strip=True) for t in q.select(".tag")],
})
next_link = soup.select_one("li.next a") # 找「下一页」链接
page_url = next_link["href"] if next_link else None
time.sleep(1) # 页间节流,关键!循环的骨头就一句:next_link 找得到就接着翻,找不到(最后一页)置 None,循环收工40。
这是本章唯一一段「稍微像算法」的代码,而它依然是模式识别:找到元素、取出内容、翻页、重复。
书里的原话:网页抓取的 rest 只是迭代41。
3.9 章末挑战:早间自动化(书里的「Your Challenge」)
本章的练习题是全书设计最完整的一道综合题,规则本身就是一份工程规格42:
任务:每天早 8 点自动完成——从新闻网站抓当日头条(BBC、Reuters 或本地站);
存进 daily_news/ 下带时间戳的文本文件;把昨天的文件自动挪进 archive/;
清理多余空白与换行;用 schedule 排期。
规则(照抄书的):
- 必须用 CCG 框架与 ChatGPT 协作生成代码;
- 只允许用 requests、BeautifulSoup、os、shutil、datetime、schedule;
- 所有路径用相对路径;
- 脚本必须在 VS Code 里不改一行就能跑。
这四条规则每一条都有用意:规则 1 练的是本章的方法本体;
规则 2 逼你想清楚「哪些库各管哪段」;规则 3 是可移植性的最低要求
(绝对路径 /Users/yourname/... 一换机器就死);规则 4 是「可运行」的定义——
交出去的脚本不该附带 oral tradition(口头传说:只有你知道的那些启动步骤)。
完成它的三个台阶:先手工跑通「抓取 → 存文件」;再接「归档 + 清理」; 最后挂 schedule。每上一个台阶跑一次,确认上一台阶的行为没变—— 这就是第四章「先锁行为再动结构」的自动化版。
3.10 章末 Key Terms 六词
原书收尾的六个术语,照收43:
| 术语 | 含义 |
|---|---|
| Automation(自动化) | 用代码无需人工干预地执行重复任务 |
| Workflow(工作流) | 为达成目标而依次运行的一系列自动化步骤 |
| Standard Library(标准库) | Python 内置、无需额外安装的模块 |
| Selector(选择器) | 抓取时定位 HTML 元素的模式(类 CSS 语法) |
| Scheduler(调度器) | 按设定时刻或间隔触发任务的函数或库 |
| Idempotent Script(幂等脚本) | 重复运行不会产生意外副作用的脚本 |
「幂等」一词值得多停一秒:它是自动化的安全属性。一个幂等的清理脚本, 今天跑了、明天又跑,结果与只跑一次相同;非幂等的脚本(比如「给所有文件加日期后缀」), 重复运行会把名字越改越长。写任何会反复跑的脚本时,先问:它幂等吗?
3.11 当自动化出错时(书里散落的排障线)
本章没设专节讲排障,但散着几条值得聚拢的线:
- 先看清脚本的「眼睛」再看它的「手」:自动化脚本的第一批 Bug 几乎都是「看见的东西不对」
(路径错了、扩展名大小写不一致、
iterdir()把目录也当文件)—— §3.2 的「先侦察」就是为这类错准备的; - 删除操作永远最后写、最先审:os.remove/rmtree 不可逆,书里的清理练习都先让 AI 「加备份再删」「移动代替删除」44——照做;
- 调度脚本要能看到心跳:§3.4 的日志在排障时就是黑匣子—— 任务「没跑」和「跑了但失败了」是两种病,日志一行字就能区分。
3.12 安装坑的处理示范(书里的一个真实片段)
书里给了一个很小的真实场景:pygame 装不上怎么办。它出现在第六章, 但处理套路是全书的通例,值得提前在这里立住:
不要猜,把报错贴给 AI。 原话:「If you run into an installation error, do not guess, but paste the error into ChatGPT」43——附的提示是「Explain why pygame is not installing and suggest the next steps based on this error message.」。
这个「不猜,贴」的动作是第四章「复现并记录」的最小版:报错文本本身就是复现记录, 而「别猜」挡住的是新手最常见的弯路——按印象重装、换源、乱升级, 每一步都可能把环境弄得更糟。贴报错之前的一个动作:确认报错是完整的 (从 Traceback 第一行到最后一行),掐头去尾的报错会让 AI 和你一样瞎。
3.13 本章方法的一句话地图
收一张速查卡——五种最常见的「卡住」,各配本章的一招:
| 卡住了 | 用哪招 |
|---|---|
| 不知该自动化什么 | 「发现重复就问能不能让 Python 拿走」(§3.1) |
| 不知道文件夹里有什么 | 先 iterdir() 打印,把清单贴给 AI 设计策略(§3.2) |
| 脚本要每天跑 | schedule 三行骨架;无人值守换 cron(§3.5) |
| 要抓的信息在网页里 | requests 取回 + BeautifulSoup 按选择器切片 + 礼貌停顿(§3.8) |
| 要抓很多页 | 找「下一页」链接的 while 循环(§3.8 例三) |
五招共用一条根:先让机器或 AI 看见现状,再谈怎么处理。 「看见现状」在文件场景是打印清单,在网页场景是先看 HTML 结构, 在调度场景是先跑一次手动——跳步的人返工最多。
3.14 爬虫提示模板背后的设计(书里最值得拆的一条提示)
§3.8 给了抓取提示的模板,这条提示值得逐部件拆——因为它的每个部件都对应一类典型失败:
「用 requests 和 BeautifulSoup 写脚本抓 [URL]。提取:[条目1、2、3]。 结果以字典列表返回。必须:带解释性注释;缺字段要优雅处理;用 try/except; 不引额外依赖;在 VS Code 里能跑;假定用户会自己 pip install requests beautifulsoup4。 只返回干净可读的代码,不要多余文字。」45
| 部件 | 防的失败 |
|---|---|
| 指定 URL 与提取项 | AI 瞎编网站结构与字段名 |
| 字典列表返回 | 输出形态不可解析(自由文本) |
| 带注释 | 你读不懂就维护不了 |
| 缺字段优雅处理 | 某个商品没价格时整段崩溃 |
| try/except | 网络抖动时裸奔 |
| 不引额外依赖 | 环境缺库脚本报 ImportError |
| 只返回代码 | 解释性文字粘进 .py 文件成语法错 |
七个部件,七类失败——这条提示是 CCG 里 Constraints 一栏的教科书。 用熟了可以整体背下来,换 URL 换提取项即用。
3.15 分页循环的另一种读法:状态机的视角
§3.8 例三的 while 循环,还有一种读法能帮你在更复杂的站点上推广它—— 把它看成一个小状态机:
状态 = 下一页的地址(初始 /page/1/)
│
▼
有状态? ──没有──→ 收工
│有
▼
抓该页 → 提取数据 → 从页面里找下一页地址 → 更新状态 → 回开头这个视角的好处:当真实站点的分页不按「下一页链接」走(改成页码按钮、 POST 翻页、无限滚动),你只需改「更新状态」那一步的写法,循环骨架不动。 书里用 quotes.toscrape 是因为它把分页模式做到了最简; 真实世界只是状态转移变复杂,结构永远是这样。
3.16 早间巡检脚本的第四圈:书末的升级提示逐条对账
§3.6 的巡检脚本跑通后,书里给了一条升级提示:「改进这个工作流:压缩旧备份、 发报告邮件、排除大于 1GB 的文件」46。把三个升级各自会引入什么摊开—— 这是一条「从练习到生产」的距离表:
| 升级 | 新引入的库/概念 | 难度 |
|---|---|---|
| 压缩旧备份 | shutil.make_archive(已在 §3.3 见过) | 低 |
| 排除 >1GB 文件 | item.stat().st_size > 1_000_000_000(文件大小检查) | 低 |
| 发报告邮件 | smtplib 或 API 型邮件服务(书里没细讲) | 中——需要外部凭据 |
前两个在书的词汇表内,第三个超出了——它要引入 SMTP 配置或第三方 API, 属于「书里指方向、你自行补细节」的那类。遇到这种,老办法:拆成小步、 「先发一封纯文本给自己」为第一目标,跑通后再加格式。
3.17 章节的隐藏主角:组合
回看全章,四个库(os、shutil、datetime、schedule)没有一个难—— 难的是 §3.6 把它们合体的那一段:morning_audit 一段函数里, os 的眼、shutil 的手、datetime 的钟各自只做一件事,schedule 在门外按点敲门47。 书里这一节的标题就叫「Combining All Four Libraries: A Real Automation Workflow」。
这就是「学编程」与「会编程」的分界:单个 API 谁都查得到,组合才需要判断。 判断的标准本章已经给了:先小后链、幂等、先侦察、留日志。 四个标准配上四个库,这一章的内容就闭环了。
3.18 练习的验收清单(章末挑战怎么算做完)
书末挑战没有标准答案,这一节给一份可自检的验收清单——全过才算完成:48
□ 早 8 点无人触发时,手动调用同一函数也能跑(调度只是壳)
□ 连跑两次:第二次不报错、不重复加日期(幂等)
□ 昨天的文件确实进了 archive/,且只挪了一份
□ 文本里无多余空白(肉眼抽查三条头条)
□ 换一天跑,新文件落在新的日期戳文件名里
□ 全程只用规定的六个库
□ 路径全是相对的,把文件夹拷到别处照样跑七格全勾,这个练习的价值才兑现;勾不满的格子,就是下一轮的 CCG 提示。 「自动化的验收从来是行为而不是代码」——这句是 §3.1 总原则在作业上的最后一遍复述。
3.19 章节的暗线:从「玩具数据」到「真实数据」的梯度
回看全章,四个例子的网站是精心设计的教学梯度,书里没点破,我们补上:
blog.python.org → 最简:一个选择器,单页,字段规整(标题+链接)
books.toscrape.com → 中阶:多个选择器嵌套(卡片→价格/库存),单页
quotes.toscrape.com → 高阶:再加分页循环——状态、节流、循环退出三个站点是同一批人(toscrape 系列练习站)维护的,字段故意规整——
真实网站不会这么乖:选择器可能每周变、字段可能缺失、列表页可能混着广告位。
书里停在梯度顶端,我们的提醒:从 quotes.toscrape 毕业后的第一步,
是选一个真实的小站点,接受「选择器失效时脚本报错」这个新常态,
并给脚本配上 §3.11 的失败模式意识(抓取段的死法:选择器变了抓回空列表——
先 print(len(items)) 再怀疑别的)。
3.20 「收割」的另一半:抓完之后的整理(书末结论的回扣)
§3.1 引了书里的话:互联网从「浏览的地方」变成「收割的地方」49。 「收割」只说了一半;本章后段(文本处理)补了另一半——收回来的东西多半不能直接用: 抓回的名言带 HTML 实体、新闻带导航栏文字、价格带货币符号。 书里的清洗流水线(去标签/转小写/合并空格)就是收割后的打谷场50。
抓与洗是一条流水线的两段,分章只是教学便利:实际项目里, scrape 的输出往往直接喂给 clean(抓完即洗),再喂给第五章的归档或第八章的报表。 写第一个爬虫时就把「清洗函数」的位置留出来——哪怕是恒等函数(原样返回), 结构上也是对的。
3.21 一句话地图:五件事各归谁
收尾一张表——日常杂务的五件事,本章教的归属:
| 事 | 谁的活 | 本章哪节 |
|---|---|---|
| 看(侦察现状) | os + iterdir | §3.2 |
| 搬(复制移动) | shutil | §3.3 |
| 记(时间戳日志) | datetime | §3.4 |
| 等(按点触发) | schedule | §3.5 |
| 收(网页数据) | requests + BeautifulSoup | §3.8 |
「看搬记等收」五个字,配上四个库一个框架,就是本章全部。51 字比库少一个——因为「等」与「搬」可以合流(巡检脚本),「看」与「收」可以合流 (先侦察页面再抓取)。真正的学习成果不是记住五个字,是下次杂务出现时, 本能地问:这事归哪个字?
3.22 四个脚本的最小骨架(抄回书里的版本,出行速查)
本章的五个脚本拆得细,但每一段的「最小可认骨架」只有两三行。收成一张表, 半年后想不起来时,凭骨架就能认出是哪个模式、回哪一节找细节52:
| 模式 | 骨架(关键两行) | 全章哪节 |
|---|---|---|
| 批量改名 | for f in folder.iterdir(): + f.rename(f.with_name(new)) | §3.3 |
| 整夹备份 | timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M") + shutil.copytree(src, dst) | §3.4 |
| 定时心跳 | while True: + schedule.run_pending() + time.sleep(1) | §3.5 |
| 分页收割 | while page_url: + page_url = next_link["href"] if next_link else None | §3.9 |
这张表同时也是本章的「新词含量」自检:四行骨架里的每个名字(iterdir、copytree、 run_pending、select_one)在对应小节都单独讲过——表上任何一个词看不懂, 就是那一节欠了一次复读,不必从头翻章。
补第五行——文本处理没有进「五件事」,因为书把它归在场景二里,但骨架同样值得存档:
re.findall(pattern, text) 两行,从日志抠邮箱(§3.7)。「看搬记等收」之外,
再加一个「提」字:杂务的第六件事,是从乱文本里提取模式。
判断(我们的,不是书里的): 本章「标准库优先」的立场值得单独记一笔: 五个杂务脚本没有一个引入第三方库(抓取除外),这不是节俭,是维护成本的远见—— 标准库随 Python 自带,不存在「作者停更、依赖腐坏」的问题; 自动化脚本的特点是「写好就忘、出事才回来看」,依赖越少,五年后它还能跑的概率越高。 如果错,会错在: 标准库的方案常常更啰嗦(二十行正则 vs 一行库调用); 对「明天就用、下周就换」的一次性脚本,装个库反而是省的。 判据是脚本的生命周期:活得久的求稳,活得短的求快。
4. 作者的判断与证据
有演示支撑的判断:
- 「标准库覆盖自动化主体」——本章用五个脚本(改名、备份、日志、排期、巡检)支撑, 论证是归纳式的但例子密度足够6;
- 「抓取 = requests + BeautifulSoup + 选择器」——三个递进例子(标题、价格、分页)完整覆盖, 是本章最扎实的部分33。
经验之谈:
- 「把文件夹清单喂给 AI 设计分类策略」——实用但非唯一;简单分类规则手写更快; AI 的价值在「你想不到的维度」11;
- 「礼貌停顿 1 秒」——经验值;严肃项目应读目标站的 robots.txt 与服务条款, 书里完全没提(见边界)。
推测:
- 「os/shutil/datetime/schedule 能自动化专业人士日常的一半」——数字无出处, 方向可信:文件与时间相关杂务确实是高频6。
5. 边界与局限
- 合规完全缺席:robots.txt(网站声明「哪里不许爬」的文件)、服务条款、版权—— 本章一个字没提。书里的三个目标站(blog.python.org、books.toscrape.com、quotes.toscrape.com) 都是为练习而设的宽松站点,把这个习惯带到真实网站会踩法律与道德坑(我们的提醒,不在书里);
- 反爬空白:真实网站有登录、JS 渲染、验证码、IP 封禁,本章的「请求 + 解析」模型只覆盖最简单的静态页;
- schedule 的常驻限制(见 §3.5 的补充):脚本停 = 排期停;
- 删除操作的风险:清理脚本(os.remove、rmtree)书里没讲「先备份再删」的默认纪律, 只在升级对话里让 AI 补——自己写时先备份(我们的提醒);
- 编码与异常:读文本文件没提编码参数(中文 Windows 环境常踩
UnicodeDecodeError), 异常处理全靠 AI 补的 try/except。
6. 可带走的
本章主线例子,一行写完: 下载夹清单 → 贴给 AI 设计分类 → morning_audit 脚本 (按扩展名分类→整夹备份→写日志,每天 8 点 schedule 触发)→ 追问「压缩旧备份、发邮件、跳过 1GB」 → 幂等写法保重复运行安全。
- 自动化的反射:发现自己在重复 → 「Python + ChatGPT 能替我把它拿走吗?」;
- 先小后链:小脚本能跑,再串工作流;别上来造系统;
- os 管手、shutil 管叉车、datetime 管钟、schedule 管闹钟——四库分工一句话记牢;
- 先侦察后自动化:列出目标文件夹真实内容,喂给 AI 设计策略——机器看数据,AI 帮你想;
- 改名三件套:splitext 拆扩展名、join 跨平台拼路径、幂等 mkdir 防重跑报错;
- 日志是自动化的心跳:每次运行留一行,排查全靠它;
- schedule 三行骨架:every().day.at("HH:MM").do(函数) + run_pending() + sleep(1);
- 文本提取 = 正则 + csv:模式串不用背,让 AI 写、自己看懂大意;
- 抓取 = requests(取回) + BeautifulSoup(切片) + 选择器(定位) + sleep(礼貌);
- 分页就一句:找得到「下一页」链接就继续,找不到就收工——抓取本质是模式识别加迭代。
7. 原文地图
| 主题 | 原书章 | 原文位置 |
|---|---|---|
| 时间漏在小事里 | Automating Tedious Tasks | text/17-ch05-5-automating-tedious-tasks.txt:18(搜「performance reviews」) |
| 别等全懂,今天就开始 | 同上 | text/17-ch05-5-automating-tedious-tasks.txt:558(搜「understand everything」) |
| 重复→能不能让 Python 拿走 | 同上 | text/17-ch05-5-automating-tedious-tasks.txt:1446(搜「off my plate」) |
| os 六件套 | 同上 | text/17-ch05-5-automating-tedious-tasks.txt:119(搜「Essential os tools」) |
| 清单喂 AI 设计分类 | 同上 | text/17-ch05-5-automating-tedious-tasks.txt:107(搜「sorting strategy」) |
| 批量改名练习 | 同上 | text/17-ch05-5-automating-tedious-tasks.txt:151(搜「enumerate」) |
| shutil 五函数、备份脚本 | 同上 | text/17-ch05-5-automating-tedious-tasks.txt:203(搜「make_archive」) · text/17-ch05-5-automating-tedious-tasks.txt:240(搜「Backup completed」) |
| datetime 四大用途、日志 | 同上 | text/17-ch05-5-automating-tedious-tasks.txt:268(搜「unique filenames」) · text/17-ch05-5-automating-tedious-tasks.txt:296(搜「Daily check」) |
| schedule 骨架 | 同上 | text/17-ch05-5-automating-tedious-tasks.txt:364(搜「every().day.at( 23:00 )」) |
| 排期三条路 | 同上 | text/17-ch05-5-automating-tedious-tasks.txt:950(搜「Manual scheduling」) |
| 早间巡检 | 同上 | text/17-ch05-5-automating-tedious-tasks.txt:447(搜「morning_audit」) |
| 文本工具箱与邮箱正则 | 同上 | text/17-ch05-5-automating-tedious-tasks.txt:804(搜「pattern matching」) · text/17-ch05-5-automating-tedious-tasks.txt:873(搜「findall」) |
| 抓取两工具 | 同上 | text/17-ch05-5-automating-tedious-tasks.txt:1040(搜「browser-in-code」) |
| 抓取提示模板(CCG) | 同上 | text/17-ch05-5-automating-tedious-tasks.txt:1104(搜「Model Prompt」) |
| 例一博客标题 | 同上 | text/17-ch05-5-automating-tedious-tasks.txt:1218(搜「post-title」) |
| 例二商品价格 | 同上 | text/17-ch05-5-automating-tedious-tasks.txt:1304(搜「product_pod」) |
| 例三分页循环 | 同上 | text/17-ch05-5-automating-tedious-tasks.txt:1398(搜「while page_url」) |
| 幂等脚本定义 | 同上 | text/17-ch05-5-automating-tedious-tasks.txt:1497(搜「Idempotent Script」) |
| 章末挑战规则 | 同上 | text/17-ch05-5-automating-tedious-tasks.txt:1501(搜「Morning Automation」) · text/17-ch05-5-automating-tedious-tasks.txt:1532(搜「requests, BeautifulSoup」) |
| 删除前备份的迭代建议 | 同上 | text/17-ch05-5-automating-tedious-tasks.txt:778(搜「Keep a backup」) |
| 安装报错不猜原则(跨章引用) | Making an Interactive Game | text/18-ch06-6-making-an-interactive-game.txt:1149(搜「do not guess」) |
Footnotes
-
出处:「Automating Tedious Tasks」第 18 段(
text/17-ch05-5-automating-tedious-tasks.txt:18,搜「performance reviews」)。 ↩ -
出处:「Automating Tedious Tasks」第 21 段(
text/17-ch05-5-automating-tedious-tasks.txt:21,搜「negotiation with boredom」)。 ↩ -
出处:「Automating Tedious Tasks」第 24 段(
text/17-ch05-5-automating-tedious-tasks.txt:24,搜「extra pair of hands」)。 ↩ -
出处:「Automating Tedious Tasks」第 558 段(
text/17-ch05-5-automating-tedious-tasks.txt:558,搜「understand everything」)。原文:「The fastest way to learn automation is by automating something today.」 ↩ -
出处:「Automating Tedious Tasks」结论第 1446 段(
text/17-ch05-5-automating-tedious-tasks.txt:1446,搜「off my plate」)。 ↩ -
出处:「Automating Tedious Tasks」Points to Remember(
text/17-ch05-5-automating-tedious-tasks.txt:1459,搜「thrives on clarity」)。原文:「Automation thrives on clarity. Before writing code, define exactly what needs to happen, inputs, outputs, and rules.」 ↩ ↩2 ↩3 -
出处:「Automating Tedious Tasks」Points to Remember(
text/17-ch05-5-automating-tedious-tasks.txt:1462,搜「Start small」)。 ↩ -
出处:「Automating Tedious Tasks」第 119 段(
text/17-ch05-5-automating-tedious-tasks.txt:119,搜「Essential os tools」)。 ↩ -
出处:「Automating Tedious Tasks」第 71 段(
text/17-ch05-5-automating-tedious-tasks.txt:71,搜「its hands」)。 ↩ -
出处:「Automating Tedious Tasks」第 107 段(
text/17-ch05-5-automating-tedious-tasks.txt:107,搜「sorting strategy」)。 ↩ -
出处:「Automating Tedious Tasks」第 116 段(
text/17-ch05-5-automating-tedious-tasks.txt:116,搜「raw data」)。原文:「The machine sees the raw data, and ChatGPT helps you think about it.」 ↩ ↩2 -
出处:「Automating Tedious Tasks」第 151 段(
text/17-ch05-5-automating-tedious-tasks.txt:151,搜「enumerate」)。 ↩ -
出处:「Automating Tedious Tasks」第 178 段(
text/17-ch05-5-automating-tedious-tasks.txt:178,搜「preserves date-created」)。 ↩ -
出处:「Automating Tedious Tasks」第 203 段(
text/17-ch05-5-automating-tedious-tasks.txt:203,搜「make_archive」)。 ↩ -
出处:「Automating Tedious Tasks」第 184 段(
text/17-ch05-5-automating-tedious-tasks.txt:184,搜「forklift」)。 ↩ -
出处:「Automating Tedious Tasks」第 240 段(
text/17-ch05-5-automating-tedious-tasks.txt:240,搜「Backup completed」)。 ↩ -
出处:「Automating Tedious Tasks」第 255 段(
text/17-ch05-5-automating-tedious-tasks.txt:255,搜「production-quality」)。 ↩ -
出处:「Automating Tedious Tasks」第 268 段(
text/17-ch05-5-automating-tedious-tasks.txt:268,搜「unique filenames」)。 ↩ -
出处:「Automating Tedious Tasks」第 299 段(
text/17-ch05-5-automating-tedious-tasks.txt:299,搜「heartbeat of automation」)。 ↩ -
出处:「Automating Tedious Tasks」第 305 段(
text/17-ch05-5-automating-tedious-tasks.txt:305,搜「rotating log」)。 ↩ -
出处:「Automating Tedious Tasks」第 311 段(
text/17-ch05-5-automating-tedious-tasks.txt:311,搜「truly automations」)。 ↩ -
出处:「Automating Tedious Tasks」第 62 段(
text/17-ch05-5-automating-tedious-tasks.txt:62,搜「no pride」)。 ↩ -
出处:「Automating Tedious Tasks」第 385 段(
text/17-ch05-5-automating-tedious-tasks.txt:385,搜「Telegram」)。 ↩ -
出处:「Automating Tedious Tasks」第 950 段(
text/17-ch05-5-automating-tedious-tasks.txt:950,搜「Manual scheduling」)。 ↩ -
出处:「Automating Tedious Tasks」第 29–33 段(
text/17-ch05-5-automating-tedious-tasks.txt:394,搜「Morning Folder Audit」)。 ↩ -
出处:「Automating Tedious Tasks」Key Terms(
text/17-ch05-5-automating-tedious-tasks.txt:1497,搜「Idempotent Script」)。 ↩ -
出处:「Automating Tedious Tasks」第 546 段(
text/17-ch05-5-automating-tedious-tasks.txt:546,搜「1GB」)。 ↩ -
出处:「Automating Tedious Tasks」第 37–38 段(
text/17-ch05-5-automating-tedious-tasks.txt:804,搜「pattern matching」)。 ↩ -
出处:「Automating Tedious Tasks」第 873 段(
text/17-ch05-5-automating-tedious-tasks.txt:873,搜「findall」)。 ↩ -
出处:「Automating Tedious Tasks」第 895 段(
text/17-ch05-5-automating-tedious-tasks.txt:895,搜「remove duplicates」)。 ↩ -
出处:「Automating Tedious Tasks」第 908 段(
text/17-ch05-5-automating-tedious-tasks.txt:908,搜「cleanup pipelines」)。 ↩ -
出处:「Automating Tedious Tasks」第 1025 段(
text/17-ch05-5-automating-tedious-tasks.txt:1025,搜「harvest」)。 ↩ -
出处:「Automating Tedious Tasks」第 1040 段(
text/17-ch05-5-automating-tedious-tasks.txt:1040,搜「browser-in-code」)。 ↩ ↩2 -
出处:「Automating Tedious Tasks」第 1055 段(
text/17-ch05-5-automating-tedious-tasks.txt:1055,搜「install explicitly」)。 ↩ -
出处:「Automating Tedious Tasks」第 1104 段(
text/17-ch05-5-automating-tedious-tasks.txt:1104,搜「Model Prompt」)。 ↩ -
出处:「Automating Tedious Tasks」Key Terms(
text/17-ch05-5-automating-tedious-tasks.txt:1491,搜「Selector」)。 ↩ -
出处:「Automating Tedious Tasks」第 1209 段(
text/17-ch05-5-automating-tedious-tasks.txt:1209,搜「Polite pause」)。 ↩ -
出处:「Automating Tedious Tasks」第 1304 段(
text/17-ch05-5-automating-tedious-tasks.txt:1304,搜「product_pod」)。 ↩ -
出处:「Automating Tedious Tasks」第 1328 段(
text/17-ch05-5-automating-tedious-tasks.txt:1328,搜「CSV exporter」)。 ↩ -
出处:「Automating Tedious Tasks」第 1398 段(
text/17-ch05-5-automating-tedious-tasks.txt:1398,搜「while page_url」)。 ↩ -
出处:「Automating Tedious Tasks」Points to Remember(
text/17-ch05-5-automating-tedious-tasks.txt:1471,搜「pattern recognition」)。 ↩ -
出处:「Automating Tedious Tasks」Your Challenge(
text/17-ch05-5-automating-tedious-tasks.txt:1501,搜「Morning Automation」)。 ↩ -
出处:「Making an Interactive Game」第 1149 段(
text/18-ch06-6-making-an-interactive-game.txt:1149,搜「do not guess」)。原文:「If you run into an installation error, do not guess, but paste the error into ChatGPT」。 ↩ ↩2 -
出处:「Automating Tedious Tasks」第 778 段(
text/17-ch05-5-automating-tedious-tasks.txt:778,搜「Keep a backup」)。 ↩ -
出处:「Automating Tedious Tasks」第 1104 段(
text/17-ch05-5-automating-tedious-tasks.txt:1104,搜「Model Prompt」)。 ↩ -
出处:「Automating Tedious Tasks」第 546 段(
text/17-ch05-5-automating-tedious-tasks.txt:546,搜「1GB」)。 ↩ -
出处:「Automating Tedious Tasks」第 388 段(
text/17-ch05-5-automating-tedious-tasks.txt:388,搜「Combining All Four」)。 ↩ -
(我们的验收清单;标准源自本章 Points to Remember 与 Key Terms 的原文口径,见
text/17-ch05-5-automating-tedious-tasks.txt:1459与:1482。) ↩ -
出处:「Automating Tedious Tasks」第 1025 段(
text/17-ch05-5-automating-tedious-tasks.txt:1025,搜「harvest」)。 ↩ -
出处:「Automating Tedious Tasks」第 908 段(
text/17-ch05-5-automating-tedious-tasks.txt:908,搜「cleanup pipelines」)。 ↩ -
(我们的五字归纳;各库的原文分工见
text/17-ch05-5-automating-tedious-tasks.txt:62、:184、:264、:311、:1037。) ↩ -
出处:「Automating Tedious Tasks」:改名循环见
text/17-ch05-5-automating-tedious-tasks.txt(搜「renames all files」);备份骨架见text/17-ch05-5-automating-tedious-tasks.txt:228(搜「strftime」)与:237(搜「copytree」);常驻循环见:1209(搜「Polite pause」)前后的while True段;分页循环见:1410(搜「while page_url」)。 ↩