将微信公众号文章保存为 PDF / Markdown,方便导入 NotebookLM 等工具学习。
基于搜狗微信搜索发现文章,使用 Playwright 浏览器自动化抓取正文,支持断点续跑和多种防限额策略。
- 按公众号名称批量抓取 — 通过搜狗微信搜索发现目标公众号的文章
- 按文章链接直接导出 — 支持单个链接或链接文件批量处理
- PDF + 可选 Markdown 导出 — 图片自动下载到本地
- 断点续跑 — 基于 SQLite 记录进度,中断后自动恢复
- 防限额策略 — 随机延时、自动放慢、强制冷却、限频退避
- 验证码手动处理 — 非无头模式下可手动完成验证码后继续
- 主题词 / 时间范围过滤 — 只导出感兴趣的文章
- 目标数量控制 — 达到指定 PDF 数量后自动停止
# 安装 Python 依赖
pip install requests beautifulsoup4 markdownify playwright
# 安装 Playwright 浏览器(首次使用)
playwright install chromium
# 抓取单个公众号的所有文章
python getWechatArticles.py --account "小林coding"
# 从文件读取多个公众号(每行一个名称)
python getWechatArticles.py --accounts-file accounts.txt
# 导出单个链接
python getWechatArticles.py --url "https://mp.weixin.qq.com/s/xxxxx"
# 从文件读取多个链接(每行一个 URL)
python getWechatArticles.py --urls-file urls.txt
# 只导出包含 "AI" 或 "agent" 的文章
python getWechatArticles.py --account "小林coding" --topics "AI,agent"
# 只导出 2024-01-01 到 2024-12-31 之间的文章
python getWechatArticles.py --account "小林coding" --start-date 2024-01-01 --end-date 2024-12-31
python getWechatArticles.py --account "小林coding" --export-md
python getWechatArticles.py --account "小林coding" --show-browser
| 参数 |
默认值 |
说明 |
--account |
"" |
单个公众号名称 |
--accounts-file |
"" |
文件路径,每行一个公众号名称 |
--url |
"" |
单个微信文章链接 |
--urls-file |
"" |
文件路径,每行一个微信文章链接 |
四种输入源至少提供一个,可组合使用。
| 参数 |
默认值 |
说明 |
--output-dir |
output |
输出目录 |
--export-md |
关闭 |
额外导出 Markdown 文件 |
--db |
wechat_account_pipeline.sqlite3 |
SQLite 状态库路径 |
--retry-limit |
3 |
单篇导出最大重试次数 |
| 参数 |
默认值 |
说明 |
--topics |
"" |
主题词,逗号分隔,如 "AI,agent,llm" |
--topic-mode |
any |
any=命中任一词即保留,all=必须全部命中 |
--start-date |
"" |
起始日期,格式 YYYY-MM-DD |
--end-date |
"" |
结束日期,格式 YYYY-MM-DD |
--target-pdf-count |
0 |
目标 PDF 数量,0=不限 |
| 参数 |
默认值 |
说明 |
--max-search-pages |
30 |
最大搜索页数,0=不限 |
--max-no-progress-pages |
10 |
最大连续无新文章页数 |
--max-open-articles |
120 |
发现阶段最多打开正文数,0=不限 |
--max-runtime-minutes |
60 |
发现阶段最大运行分钟数,0=不限 |
--max-open-per-page |
6 |
每个搜索页最多打开多少条候选正文 |
--include-combined-query |
关闭 |
额外生成 "公众号名 + 所有 topics 合并" 的搜索词 |
| 参数 |
默认值 |
说明 |
--base-sleep-search |
1.2 |
搜索页基础等待秒数 |
--base-sleep-open |
1.5 |
打开正文基础等待秒数 |
--base-sleep-export |
1.0 |
导出阶段基础等待秒数 |
--slowdown-after-opens |
15 |
每打开多少篇正文后自动放慢 |
--slowdown-multiplier |
1.8 |
放慢倍数 |
--cooldown-every-opens |
30 |
每累计打开多少篇强制冷却 |
--cooldown-seconds |
75 |
强制冷却秒数 |
--backoff-on-frequent |
1 |
遇到"访问过于频繁"自动退避,1=开启,0=关闭 |
--max-fail-streak |
5 |
连续失败多少次后暂停当前公众号 |
| 参数 |
默认值 |
说明 |
--cookie |
无 |
浏览器 Cookie 字符串 |
--show-browser |
关闭 |
显示浏览器窗口(遇到验证码可手动处理) |
--reset-account |
"" |
重置指定公众号的状态后运行 |
--reset-all |
关闭 |
清空全部状态库后运行 |
output/
└── 公众号名称/
└── 文章标题_哈希值/
├── 文章标题.pdf
├── 文章标题.md # 仅 --export-md 时生成
└── images/
├── img_001.jpg
└── img_002.png
程序使用 SQLite 记录每个公众号的搜索进度和每篇文章的处理状态。如果中途中断(Ctrl+C 或异常),再次运行相同命令会自动从断点继续。
# 重置某个公众号的状态(重新搜索)
python getWechatArticles.py --account "小林coding" --reset-account "小林coding"
# 清空所有状态
python getWechatArticles.py --account "小林coding" --reset-all