@sovovs/wechat-article-crawler
v1.1.3
Published
Agent-friendly CLI for listing and saving WeChat public account articles
Readme
bycli微信公众号文章
面向 agent 和自动化流程的微信公众号文章 CLI。支持输出结构化文章 JSON,或将文章正文保存为 Markdown。
环境要求
- Node.js 18 或更高版本
- 可访问微信公众平台的有效 token 和 Cookie
文章保存的默认文件系统安全路径(目录 fd 相对写入)要求 Linux;在其他平台可通过自定义 fsImpl 适配测试或集成环境。
项目不需要安装运行时依赖。
安装 CLI
在项目目录运行:
npm link然后可以在终端调用:
wechat-crawler --help也可以不注册全局命令,直接运行:
node bin/wechat-crawler.js --help程序化 API
CommonJS 项目可以直接引用包根路径。下面的示例使用 createWechatApi 获取分页和文章正文,使用 collectArticles 收集有效文章,再将注入的 fetchArticleHtml 和 buildMarkdown 回调传给 saveArticles:
const {
createWechatApi,
collectArticles,
saveArticles,
} = require('@sovovs/wechat-article-crawler');
async function run() {
const account = { fakeid: 'Mzg2NjY2NTcyNg==', name: '前端之神' };
const wechat = createWechatApi({
token: process.env.WECHAT_TOKEN,
cookie: process.env.WECHAT_COOKIE,
});
const { articles, summary } = await collectArticles({
fakeid: account.fakeid,
fetchPage: wechat.fetchPage,
limit: 20,
});
const rows = await saveArticles({
articles,
accountName: account.name,
outputDir: './articles',
fetchArticleHtml: (article) => wechat.fetchArticleHtml(article.url),
buildMarkdown: async (_article, html) => html.replace(/<[^>]+>/g, '').trim(),
// 默认是 "suffix";CLI 的 save 命令使用 "overwrite"。
existingFilePolicy: 'suffix',
});
console.log({ summary, rows });
}
run().catch((error) => {
if (error.name === 'CrawlerError') {
console.error(error.code, error.details, error.message);
}
process.exitCode = 1;
});saveArticles 要求调用方注入 fetchArticleHtml(article) 和 buildMarkdown(article, html);示例中的转换器仅用于演示,生产环境应替换为所需的 HTML-to-Markdown 实现。公开的包根导出只有 CrawlerError、collectArticles、createWechatApi、isTrustedWechatArticleUrl 和 saveArticles 五项。
CrawlerError.code 取值为:INVALID_ARGUMENT(参数无效)、AUTH_REQUIRED(凭证无效或缺失)、REMOTE_ERROR(微信接口或网络错误)、DOWNLOAD_FAILED(文章下载失败)、CONVERSION_FAILED(Markdown 转换失败)和 FILESYSTEM_ERROR(安全文件写入失败);可同时读取只读的 error.details。
文章保存的默认安全文件写入实现要求 Linux(使用目录 fd 相对路径和 no-follow 保护)。在非 Linux 平台,默认 fsImpl 会 fail-closed;如需测试或集成适配,请显式传入自定义 fsImpl。这不影响下方 CLI 文档和命令的用法。
凭证
推荐通过环境变量传入,避免 Cookie 出现在 Shell 历史和进程列表:
export WECHAT_TOKEN="你的 token"
export WECHAT_COOKIE="你的 Cookie"也支持命令行参数:
--token <token>
--cookie <cookie>命令行参数优先于环境变量。凭证不会写入结果 JSON 或 Markdown。
list:输出文章 JSON
默认抓取该公众号的全部历史有效文章:
wechat-crawler list \
--fakeid "Mzg2NjY2NTcyNg==" \
--name "前端之神"完整 JSON 默认写到标准输出。进度写到标准错误,因此 agent 可以直接解析标准输出。
把完整 JSON 覆盖写入文件:
wechat-crawler list \
--fakeid "Mzg2NjY2NTcyNg==" \
--name "前端之神" \
--output ./result.json传入 --output 后,标准输出只返回结果文件绝对路径和文章数量。
save:保存 Markdown
wechat-crawler save \
--fakeid "Mzg2NjY2NTcyNg==" \
--name "前端之神" \
--output-dir ./articles每篇有效文章保存为:
articles/<清理后的文章标题>.md- 不额外创建公众号子目录。
- 同名文件直接覆盖。
- 标题为空或清理后为空时使用
Untitled.md。 - 最终标准输出为 JSON 汇总,进度写到标准错误。
- 单篇下载失败不会丢弃其他成功文件。
可选限制
两个子命令都支持:
--limit <数量> 最多处理的有效文章数量
--max-pages <数量> 最多请求的分页数量
--timeout <毫秒> 单次请求超时,默认 30000不传 --limit 和 --max-pages 时抓取全部历史文章。首次验证建议先使用:
wechat-crawler list --fakeid "..." --name "..." --limit 3JSON 结果
list 返回公众号、接口统计和文章元数据:
{
"schemaVersion": "1.0",
"success": true,
"account": {
"fakeid": "Mzg2NjY2NTcyNg==",
"name": "前端之神"
},
"summary": {
"totalFromApi": 1927,
"scanned": 10,
"valid": 3,
"invalid": 1,
"pages": 1
},
"articles": [],
"errors": []
}save 返回成功文件绝对路径和逐篇错误:
{
"schemaVersion": "1.0",
"success": true,
"partial": false,
"outputDirectory": "/absolute/path/articles",
"summary": {
"discovered": 1,
"saved": 1,
"failed": 0
},
"files": [],
"errors": []
}退出码
| 退出码 | 含义 | |---:|---| | 0 | 全部成功 | | 1 | 参数、凭证或微信接口整体失败 | | 2 | 部分文章下载失败 | | 3 | 结果文件或 Markdown 输出失败 |
测试
npm test免责声明
本工具仅供学习和研究使用。请控制请求频率,并遵守微信公众平台规则及适用法律。
License
Apache-2.0
