自动化脚本实战:从爬虫到日常提效的血泪总结
实验室窗外下着小雨,耳机里放着Lo-fi Beats,我一边调试一个刚写完的自动化部署脚本,一边刷着LeetCode——没错,研二了,跳槽季快到了,项目和面试两手抓。最近组里催得紧,导师还说“这个月必须把数据集更新完”,于是我不得不把手头一堆重复性工作用脚本全自动化掉。今天就来聊聊这段时间在自动化脚本上的踩坑与收获,尤其聚焦在爬虫和日常运维脚本上的一些实战经验。
为什么我又开始写爬虫了?
事情要从去年双11说起。我们实验室接了个横向项目,需要定期抓取某电商平台的商品评论数据做情感分析。一开始是手动导出,后来发现数据量太大,人工根本扛不住。产品经理(哦不,是项目负责人)直接甩过来一句:“你们不是搞AI的吗?不会写个脚本自动跑?”
行吧,写就写。但现实很骨感:反爬机制、IP封禁、验证码、动态渲染……你以为只是requests.get(url)的事?Too young.
我一开始用的是requests + BeautifulSoup,简单粗暴。结果跑了不到500条,IP就被限了。第二天改用代理池+随机User-Agent,勉强撑到2000条,然后网站升级了,评论区变成前端动态加载。好家伙,直接给我整不会了。
这时候才意识到:现代爬虫早就不是静态HTML解析那么简单了。
爬虫进阶:从“能跑”到“稳跑”
技术选型:Pyppeteer vs Selenium vs Playwright
我试过三种方案:
- Selenium:老牌工具,社区大,但启动慢、资源占用高。本地跑还行,放到服务器上经常OOM。
- Pyppeteer(Puppeteer的Python版):基于Chromium,支持无头模式,性能比Selenium好不少。但文档少,异步写法容易踩坑。
- Playwright:微软出品,支持多浏览器(Chromium/Firefox/WebKit),API更现代,还自带自动等待机制。
最后我选了 Playwright。虽然它要求Python 3.7+(还好我们实验室环境是3.9),但它的一键截图、网络拦截、设备模拟功能太香了。而且它能自动处理页面加载完成的判断,不用自己写一堆time.sleep()或者WebDriverWait。
from playwright.sync_api import sync_playwright
def fetch_comments(product_id):
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
page.goto(f"https://example.com/product/{product_id}/comments")
# 自动等待评论区域加载
page.wait_for_selector(".comment-list", timeout=10000)
comments = page.eval_on_selector_all(
".comment-item",
"els => els.map(el => el.innerText)"
)
browser.close()
return comments
注:实际项目中我会加上重试机制、异常捕获、日志记录,这里为了简洁省略了。
反爬对抗:别硬刚,要学会“伪装”
电商网站的反爬逻辑一般是:
- 检测请求频率
- 检查User-Agent是否像机器人
- 验证是否有JS执行环境(比如检测
window.chrome) - 行为分析(鼠标轨迹、点击间隔等)
我们的策略是:
- 低频请求:每请求一次 sleep(2~5秒),加随机抖动
- 真实User-Agent轮换:用
fake-useragent库 - 启用JS渲染:这正是Playwright的优势
- 使用住宅代理:公司报销了一笔云服务费,买了Luminati的代理池(学生党慎入,贵!)
另外,不要一上来就抓敏感数据。先模拟人类行为:打开首页 → 搜索商品 → 进入详情页 → 滚动到底部 → 点击“查看更多评论”。这种路径更不容易被识别为爬虫。
日常自动化:不止是爬虫
其实,爬虫只是自动化的一小部分。真正让我效率翻倍的,是那些“脏活累活”的脚本。
场景1:批量处理实验数据
我们跑深度学习模型时,每次训练都会生成一堆log、checkpoint、metrics。手动整理太痛苦。于是我写了个脚本,自动:
- 解析
train.log提取loss/acc - 压缩无用的中间文件
- 生成Markdown格式的实验报告
- 推送到GitLab仓库
#!/bin/bash
# auto_report.sh
LOG_DIR="./logs/exp_$(date +%Y%m%d)"
python parse_logs.py $LOG_DIR > report.md
tar -czf $LOG_DIR/checkpoints.tar.gz $LOG_DIR/checkpoints/
git add report.md && git commit -m "Auto report $(date)" && git push
现在每天早上喝咖啡的时候,GitLab上已经有昨晚所有实验的结果了。导师看了直呼“内卷”。
场景2:一键部署测试环境
以前每次给测试同学交付新版本,都要手动:
- 打包前端
- 构建Docker镜像
- 推送到Harbor
- 修改K8s YAML
- kubectl apply
现在?一个命令搞定:
# deploy_dev.py
import os
os.system("npm run build")
os.system("docker build -t myapp:$(git rev-parse --short HEAD) .")
os.system("docker push registry.xxx/myapp:$(git rev-parse --short HEAD)")
os.system("kubectl set image deployment/myapp *=registry.xxx/myapp:$(git rev-parse --short HEAD)")
print("✅ 已部署到测试环境!快去群里@测试小姐姐!")
运维大哥看到后说:“你这脚本要是再加个回滚功能,我就给你颁个‘最佳摸鱼奖’。”(其实是夸我)
踩过的坑:血泪教训
1. 别信“一次写好就能永远跑”
上周五晚上10点,我正准备下班,突然收到告警:爬虫脚本挂了。一看日志:
Error: Element .comment-list not found within 10000ms
原来网站前端重构了,CSS类名从.comment-list改成了.review-container。我当时真的想砸电脑。
教训:
- 关键选择器不要硬编码,最好用XPath或更稳定的属性(比如
data-testid) - 加监控!我后来用Prometheus + Alertmanager做了失败告警
- 写单元测试!哪怕只是mock一个HTML片段
2. 权限问题:别用root跑脚本
有次我在服务器上用root权限跑了一个rm -rf /tmp/*的清理脚本,结果手滑写成rm -rf / tmp/*……差点删库跑路。还好有备份。
现在所有脚本都用普通用户运行,并且加了--dry-run模式:
if dry_run:
print(f"[DRY RUN] Would delete {file}")
else:
os.remove(file)
3. 日志!日志!日志!
早期脚本没打日志,出问题只能靠猜。现在我的脚本标配:
import logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler("script.log"),
logging.StreamHandler()
]
)
效果对比:自动化前后
| 任务 | 手动耗时 | 脚本耗时 | 频率 | 年节省工时 |
|---|---|---|---|---|
| 数据采集(爬虫) | 3小时/天 | 20分钟/天 | 每日 | ~800小时 |
| 实验报告生成 | 1小时/次 | 2分钟/次 | 每周5次 | ~240小时 |
| 测试环境部署 | 30分钟/次 | 1分钟/次 | 每日2次 | ~100小时 |
算下来,一年省了1100+小时,相当于多出半年全职工作时间。跳槽简历上都能写“通过自动化提升团队效能300%”了(笑)。
给想搞自动化的同学几点建议
- 从小处着手:别一上来就想写个“全自动运维平台”。先解决你每天最烦的那个5分钟重复操作。
- 稳定压倒一切:工作中用的技术不一定要新,但一定要稳。我在实验室折腾Rust写爬虫玩,但项目里还是乖乖用Python+Playwright。
- 文档比代码重要:脚本写完记得写README,说明怎么用、依赖什么、谁维护。不然三个月后你自己都看不懂。
- 别过度自动化:有些事手动更快。比如只跑一次的任务,写脚本可能比手动还慢。
最后
写自动化脚本这件事,本质上是在用今天的代码,买明天的时间。作为研二狗,我既要赶论文、做项目,又要刷题准备面试,时间就是命。这些脚本虽然看起来“不酷”,但实实在在让我每天多出2小时学习LeetCode。
如果你也在被重复劳动折磨,别忍了,写个脚本干它!记住:程序员的终极浪漫,就是让机器替自己打工。
对了,刚收到HR消息,下周一面。希望我的爬虫脚本能帮我抓点面经……(开玩笑的,面经还是得老老实实刷)
作者:某211软工研二在读,实验室搬砖人,业余LeetCode选手。喜欢边听《夜曲》边debug,梦想是写出永不报错的代码。

评论 0