从官网批量下载全部国家法律法规
用 AI 花 1 天时间,批量下载了全部国家法律法规,踩了 10 个坑后终于搞定
一次用 AI 做自动化爬虫的真实记录——从想法到完成,全程靠 AI 写代码,失败了 N 次,最终成功了。
起因:一个简单的需求
把国家法律法规数据库(flk.npc.gov.cn)里的法律法规 Word 文件全部下载下来,同时整理一份索引表格,方便后续导入单位数据库。
网站上有将近 3 万条记录,分 294 页,每页 100 条。如果手动点,按每页 2 分钟算,要连续点 10 小时,还不算中途可能出错。
所以:让 AI 来写自动化脚本干这个活。 AI 平台:WorkBuddy。
下面把整个过程,特别是踩坑经历,原原本本写出来,希望对有类似需求的人有帮助。
第 1 个坑:想走捷径,直接调 API,失败了
一开始,让 AI 帮分析网站的网络请求,想直接找后端 API 接口,绕过浏览器,直接把数据抓下来。理论上这样最快,不需要模拟点击,直接请求数据。但失败了。
原因是:
网站有会话验证,批量下载和批量导出的按鈕,必须通过浏览器点击才能触发,后端不接受直接的接口调用。用 curl 或 fetch 发请求,服务器要么返回空,要么直接拒绝。
教训:
用验证码防爬的网站,想绕过浏览器直接调 API,大概率行不通。踏踏实实用浏览器自动化。
第 2 个坑:浏览器自动化,以为可以“静默”运行,又失败了
换成浏览器自动化(Playwright),默认用的是 headless 模式——就是浏览器在后台跑,不弹出窗口。
脚本运行起来了,也“点击”了下载按鈕,日志显示“下载成功”,但是输出目录里没有任何文件。
没有报错,没有提示,就是没有文件。这种静默失败最难排查。
原因是:
这个网站有浏览器环境检测,headless 模式下被识别为机器人,下载请求虽然发出去了,但服务器不响应,或者下载行为被拦截。
解决方法:
强制用有界面模式(headless: false),让真实的 Chrome 窗口弹出来,模拟真人操作。这个坑浪费了将近半天时间。
第 3 个坑:脚本一旦崩溃,就得从头来
换成有界面模式后,终于开始真正下载了。但是网站不稳定,隔一会儿就出现“请求错误”页面,脚本遇到错误就停了,下载到一半断掉,要重新开始。
这个问题的解决思路是加断点续传:每下完一页,就把进度写入一个 JSON 文件。下次启动,直接从上次中断的地方继续,不用从第 1 页重新来。
{
“currentPage”: 85,
“totalPages”: 294,
“completed”: [1, 2, 3, …, 84],
“errors”: []
}
有了这个,哪怕脚本崩 100 次,总进度不会丢。
第 4 个坑(最危险):守护进程 + 异常处理写错了,Chrome 开了 N 个,系统死机
为了让脚本崩溃后自动重启,加了一个“守护进程”,专门监视下载脚本,崩了就重启。但是代码里有一个致命错误:
// 这段代码差点让电脑死机
process.on(‘uncaughtException’, (err) => {
console.error(‘出错了:’, err);
main(); // ← 问题在这里!
});
每次出现未捕获的异常,代码里会再调用一次 main(),而 main() 会启动一个新的 Chrome 浏览器。如果异常频繁触发,Chrome 进程就会指数级增加:1个→2个→4个→8个……
当时看着任务管理器里 Chrome 的进程数量从十几个涨到几十个,内存从 8G 涨到满载,最后系统直接假死。
正确的写法:
process.on(‘uncaughtException’, (err) => {
console.error(‘出错了:’, err);
process.exit(1); // 直接退出,让外部守护进程负责重启
});
自己永远不要重启自己。守护进程和业务进程要分开,守护进程管“重启”,业务进程管“干活”。
第 5 个坑:后台运行时守护进程莫名消失
修好了 Chrome 倍增的问题,把守护进程放到后台跑,结果过一段时间发现进程没了,日志里也没有报错。
原因:
当守护进程监听子进程(下载器)的输出,并把这些输出转发到自己的标准输出时,如果终端窗口关闭,输出通道(pipe)断裂,任何写操作都会触发一个 EPIPE 错误,Node.js 的默认行为是崩溃退出。
触解决方法:
子进程的输出不要转发给父进程,直接写到日志文件里:
// 不这样做
child.stdout.pipe(process.stdout);
// 这样做
child.stdout.on(‘data’, (data) => {
fs.appendFileSync(‘child_output.log’, data);
});
这个 bug 很难发现,因为没有任何报错,程序就是静默消失了。
第 6 个坑:下载的文件互相覆盖
等以为大功告成,检查输出目录,发现只有一个《批量下载文件.zip》,300 多页全都下载成了同一个文件名,只剩最后一页的内容。
原因:
网站每次下载都用相同的文件名,浏览器会直接覆盖同名文件。
触解决方法:
在下载事件里,给每个文件加上页码前缀:
page001_批量下载文件.zip
page002_批量下载文件.zip
page003_批量下载文件.zip
…
这样不仅不会覆盖,还能一眼看出哪页对应哪个文件,排查漏页非常方便。
第 7 个坑:文件名包含非法字符,解压失败
下载全部完成后,开始解压 ZIP 文件,结果有 13 个文件报错:Errno 22: Invalid argument。
原因:
一些法律法规的名称里包含 < 和> 符号,这两个字符在 Windows 文件系统里是非法字符,无法创建同名文件。
触解决方法:
解压时对文件名做一次清理,把非法字符替换为全角字符:
name = name.replace(‘<‘, ‘<‘).replace(‘>’, ‘>‘)
name = name.replace(‘:’, ‘:‘).replace(‘”‘, ‘″’)
全角字符看起来一样,但在文件系统里是完全合法的,完美解决。
第 8 个坑:XLSX 文件被 Python 报“损坏”,无法读取
下载下来的 .xlsx 文件,用常见的Python 库 openpyxl 读取,报错:File is not a zip file(文件不是 zip 格式)。
这个错误很迷惑——明明扩展名是 .xlsx,为什么说不是 zip?
原因:
现代的 .xlsx 格式本质上是 ZIP 压缩包,但这个网站导出的 .xlsx,实际上是老版 Excel 格式(.xls),只是套了一个 .xlsx 的扩展名。两种格式底层完全不同,openpyxl 只支持新格式,所以报错。
触解决方法:
改用 xlrd 库来读取(xlrd 支持老版 xls 格式),再用 openpyxl 写出新格式的 xlsx:
# 读取(用 xlrd 处理 OLE2/xls 格式)
import xlrd
wb = xlrd.open_workbook(‘page001_xxx.xlsx’)
# 写出(用 openpyxl 生成新格式)
from openpyxl import Workbook
new_wb = Workbook()
经验:
不要相信文件扩展名,处理来自网站的文件时,最好先检查一下文件实际格式。
第 9 个坑:Ctrl+C 停不掉后台进程
Windows 后台运行的隐藏进程,按Ctrl+C 完全没用,而直接 kill 进程又担心丢失当前的下载进度。
触解决方法:
实现一个“文件信号”机制——在输出目录里创建一个名为 .stop 的空文件:
New-Item -Path “D:\workbuddy\law20260430\.stop” -ItemType File -Force
守护进程和下载器每秒检查这个文件是否存在,存在就优雅退出:先保存当前进度,关闭浏览器,然后退出。进度不会丢。
第 10 个坑:Python 不在系统 PATH 里
自动后处理需要调用 Python,但是Windows 上 Python 安装路径没加入 PATH,直接调用 python 命令失败。
触解决方法:
用完整路径,并支持环境变量配置:
const pythonCmd = process.env.PYTHON_PATH
|| ‘C:\\Users\\admin\\AppData\\Local\\Programs\\Python\\Python313\\python.exe’;
最终成果
踩完这 10 个坑,经过十几个版本的迭代,最终的自动化程序稳定跑完了全部 294 页:
|
指标 |
数值 |
|
法律法规总数 |
29,317 条 |
|
下载 Word 文件数 |
28,854 个 |
|
合并索引(去重后) |
29,033 条 |
|
发现并去除重复 |
302 条 |
整个下载过程完全无人値守,自动重启、自动断点续传、完成后自动解压合并。
最终架构(简化版)
整个系统分三层:
守护进程
└── 负责:监视 + 崩溃自动重启
下载器
└── 负责:控制浏览器逐页下载
每页:全选 → 下载zip → 导出 xlsx →翻页
每页保存一次进度(断点续传)
后处理脚本
└── 下载全部完成后自动觥发
├── 解压所有 zip → law/ 目录
└── 合并所有 xlsx → law_index.xlsx(去重)
给有类似需求的人几点建议
•有些网站,需要点击才能触发的下载,不要想着调 API,直接用浏览器自动化
•headless 模式不是万能的,遇到下载失败先试试有界面模式
•守护进程和业务进程分离,异常处理里不要自己重启自己
•每个关键步骤完成后立即保存进度,断点续传是长时间任务的标配
•文件命名加上序号/页码,排查问题方便十倍
•处理来自网站的文件,不要相信扩展名,不要假设文件名合法
•在 Windows 上做后台任务,Ctrl+C 不可靠,要设计专门的停止机制
结语
这次项目最大的感受是:AI 写代码确实快,但排查 bug 还是需要人理解逻辑。每一个坑,AI 都能给出解决方案,AI 是个非常能干的执行者,但“发现问题在哪”这件事,人机协作效果最好。
整个项目从提需求到最终完成,8小时。
代码已整理为可复用的自动化技能skill,下次直接套用。
skill 和所有法律文件(截止2026-04-30)下载链接:
https://pan.baidu.com/s/1dMPLaHaJYkn5qLwQGr0aTw?pwd=love
夜雨聆风