Overview
Fetch WeChat Official Account articles to local storage, producing two outputs at once by default:
| Output | Purpose | Features |
|---|---|---|
| Markdown cleaned version | Search, citation, downstream processing | Plain-text paragraphs + localized images, automatically filters out small decorative images |
| HTML original | Faithful record, retrospective verification | Complete page + all images localized (no filtering), readable offline by double-clicking, original external links preserved in data-src for reference |
Why both are needed: Official Account share links often carry tempkey temporary credentials, and become inaccessible after expiry; Markdown cleaning loses layout and illustrations, making it impossible to retrospectively verify the original text later.The original is faithful, the cleaned version is easy to use; the two complement each other and do not replace each other.
Fetching engines:
- Direct HTTP fetching(default main route): WeChat articles are server-side rendered, and the body text and image addresses are all in the initial HTML, so a direct request suffices. Zero dependencies, fast.
- Playwright browser fallback(
--engine autoautomatic switch): enabled when the HTTP route fails or the page requires JS rendering.
Usage
# 默认:双产出,保存到 skill 内 archive/<时间戳>_<标题>/
node scripts/fetch.js "https://mp.weixin.qq.com/s/xxxxx"
# 指定输出根目录(文章产物归入其下子目录)
node scripts/fetch.js "https://mp.weixin.qq.com/s/xxxxx" "./articles/"
# 兼容旧用法:直接指定 .md 文件路径(其余产物同目录平铺)
node scripts/fetch.js "https://mp.weixin.qq.com/s/xxxxx" "./articles/my-article.md"
# 只要 Markdown 整理版 / 只要 HTML 原件
node scripts/fetch.js "https://mp.weixin.qq.com/s/xxxxx" --mode markdown
node scripts/fetch.js "https://mp.weixin.qq.com/s/xxxxx" --mode archive
# 强制走浏览器(或只走 HTTP 不装 Playwright)
node scripts/fetch.js "https://mp.weixin.qq.com/s/xxxxx" --engine playwright
node scripts/fetch.js "https://mp.weixin.qq.com/s/xxxxx" --engine http
Run with full parameters node scripts/fetch.js --help to view.
Output structure
archive/<YYYYMMDD_HHMMSS>_<文章标题>/
├── <文章标题>.md # 整理版(头部注明原文链接与 HTML 原件位置)
├── <文章标题>.html # 原件(src 已本地化,离线可读)
├── <文章标题>_assets/ # 整理版图片(智能过滤小装饰图)
└── <文章标题>_html_assets/ # 原件图片(全量保真,含小图标)
Programming interface
import { fetchWechatArticle } from './scripts/fetch.js';
const report = await fetchWechatArticle("https://mp.weixin.qq.com/s/xxxxx", {
engine: 'auto', // 'auto' | 'http' | 'playwright'
mode: 'both', // 'both' | 'markdown' | 'archive'
outputPath: null, // 输出路径(可选)
retries: 3 // Playwright 路线重试次数
});
// report: { title, url, engine, md, archive: { htmlPath, images, missing, remoteLeft, failed } }
Post-fetch check (mandatory, do not skip)
Check the script output:
- If the HTML original line starts with
[OK ], the archive is complete; if[警告], check the "missing local images" and "remaining external links" items - It is normal for remaining external links to be only the WeChat official blank placeholder
pic_blank.gif, and can be ignored - In the Markdown image statistics, "failed" should be 0; a filtered count of decorative images is normal
- If the page reports "This content has been deleted by the publisher", "Abnormal environment", etc. → the link is invalid, and the script will automatically switch engines and retry; if both engines fail, do not blindly retry the link
Pitfalls and key points
| Pitfall | Handling |
|---|---|
tempkey links expire |
Fetch immediately upon receipt, do not wait to "save it when there is time" |
The real image address is in data-src , not in src |
src which is mostly a base64 placeholder; the script already handles this, but note it when troubleshooting manually |
The URL attribute contains & , not & |
; it can only be downloaded after decoding, otherwise 403; the script already handles this |
Image domains are not limited to mmbiz.qpic.cn |
, but also include mmecoa.qpic.cn etc.; identify by the qpic.cn suffix, do not hardcode subdomains |
wx_fmt parameter determines the extension |
WeChat image URLs have no .jpg suffix; infer by ?wx_fmt=jpeg , so PNG will not be saved with a jpg name |
| svg small icons look like 0KB | The few-hundred-byte decorative icons in the original directory are not download failures; do not delete them (the original is fully faithful) |
| "Environment Abnormality" page | The engine automatically switches and retries; if it still fails, the link is invalid or verification is required |
Downstream Processing Suggestions
After scraping is complete, if the content is structured legal text such as laws and regulations, judicial documents, etc., you may during reportingprompt the user: if further formatting and organization is needed, the corresponding formatting skill can be specified (if available in the environment) to continue processing. Whether to invoke it, and which skill to invoke, is decided by the user or the upper-level process—this skill does not automatically invoke or bind to any downstream skill.
Notes
⚠️ For personal study and research only, please comply with the website's terms of service
⚠️ Frequent scraping may be rate-limited; it is recommended to control the request frequency
⚠️ The copyright of scraped content belongs to the original author
⚠️ The Playwright fallback route will automatically install chromium on first use (npx playwright install chromium); the HTTP direct scraping route has zero dependencies