公众号文章真实配图获取
铁律(不可违背)
- 绝不使用 ImageGen / AI 生成图。本账号配图一律用真实网络素材,优先 Wikimedia Commons 自由版权(链接稳定、可溯源、无版权风险)。
- 图片必须先下载到本地,再在 markdown 里用
引用;wechat-publisher 上传只认本地 jpg/png。 - 统计类/数据类图片(如「国内 19% vs 全球 5%」对比图)优先找机构原始图,没有可靠来源就不要写死数字,宁可删。
- 来源清单只留内部档,不进正文(见下「来源留档」)。成稿要干净,绝不在文末塞「配图来源」附录段落。
什么时候用
用户写了/要写一篇公众号文章,并要求配图,或你判断文章需要配图增强。典型触发:「配图最少 4 张」「给我文章配图」「这篇加几张图」。
工作流程
1. 规划配图(数量 + 主题)
- 数量:≥4 张(铁律下限),覆盖文章每个主要段落或冲突点,避免头重脚轻。
- 主题优先找事件、产品、品牌实拍图,避免纯示意图;封面选最贴合主题、信息密度高、主体居中的一张。
- 偷懒做法:直接把文章 markdown 丢给脚本
--from-md,它会解析##/###小标题自动出配图 plan 草稿(每个标题一个 item,带anchor供后续插入),你只需把 query 改成更准的关键词或确切title。
2. 写 plan JSON
为每个需求写一项。两种定位方式:
{
"items": [
{"name": "img01_harmonyos.png", "title": "File:HarmonyOS Developer Day.png"},
{"name": "img02_mate60.jpg", "query": "Huawei Mate 60", "anchor": "华为手机实拍"},
{"name": "img03_android.png", "title": "File:Android logo (2019-2023).svg", "svg": true}
]
}
- 有确切 Wikimedia 文件名用
title(最稳,避免搜错)。 - 只知道主题用
query:脚本会搜srnamespace=6(File 空间),并按「非 SVG 优先 + 像素面积大优先」自动取首位;若担心命不中,先跑--suggest打印 top5 候选挑 title 写回。 anchor(可选):小标题文本,下载后可用--inject把图片自动插到该标题下方,省去手动找位置。- SVG 必须标
"svg": true:微信不支持 SVG,脚本会经 imageinfo API 取 PNG 缩略图栅格化。
3. 运行下载脚本
# 体积默认压到 ≤1MB(微信长正文带主题CSS易超时),PNG 超体积自动转 JPEG
python scripts/fetch_images.py --plan plan.json --out images
# 命中不准时:只搜候选不下载,挑 title 写回 plan
python scripts/fetch_images.py --plan plan.json --out images --suggest
# 从 markdown 小标题自动出 plan 草稿(不下载)
python scripts/fetch_images.py --from-md article.md --out images
脚本会自动:
- 429/5xx 退避重试(默认间隔 3s,翻倍到 30s 封顶);
- SVG → PNG 栅格化;
- 用 Pillow 把宽度压到 ≤1280、JPG 质量 82,默认确保单图 ≤ 1MB(PNG 超体积自动转 JPEG 并循环降质到 quality=55 兜底);
- Pillow 缺失即明确报错,不再静默退回原图(避免大图上传挂);
- 下载后生成 images/sources.md(内部留档)和 images/plan_resolved.json(带 file 字段,供插入用);
- 打印封面候选(按长宽比正常 + 体积适中推荐 top3)。
> 命中差的题材别硬凑:像「小米1999屠场」这类历史场景,Commons 上高清实拍几乎没有,--suggest 也会空。此时提示用户人工补图,不要用无关水文图凑数。
4. 插入正文(按锚点)
两种方式:
- 手动:在 markdown 对应段落插入 。
- 自动:下载后用解析出的 plan_resolved.json 按 anchor 插入——
bash
python scripts/fetch_images.py --plan images/plan_resolved.json --out images --inject --markdown article.md
默认只打印预览,加 --apply 才真写原文件;anchor 未匹配到标题会告警。
5. 来源留档(内部,不进正文)
images/sources.md 已记录每张图来源 + 许可(CC BY / CC BY-SA / Public domain 等),仅作内部合规留档,不要复制进公众号正文。成稿保持干净。
6. 接 wechat-publisher(发布阶段)
本地图就绪后按 wechat-publisher skill 的规则推送(本 skill 不重复细节,避免两处漂移):
- 正文 markdown 用相对路径 images/xxx.jpg 引用;
- upsert_draft.py --input 传 content_markdown_path + content_base_dir;
- 封面用 thumb_image_path 本地路径(从步骤3的封面候选里挑),上传由脚本自动完成;
- Windows 上 urllib 走系统注册表代理导致偶发 SSL: UNEXPECTED_EOF,用 runner 包一层 urllib.request.install_opener(ProxyHandler({})) 强制直连再跑上传脚本。
关键约束(踩坑记录)
| 风险 | 处理 |
|---|---|
| 微信单图 ≤ 10MB,大图上传超时 | 默认压到 ≤1MB(带主题CSS长正文更稳),宽度压 1280、JPG 质量 82,PNG 超体积自动转 JPEG |
| Wikimedia 429 限流 | 下载间隔 + 退避重试 |
| 微信不支持 SVG | 先栅格化为 PNG(svg:true) |
| 数据类图片无权威来源 | 宁可不写死数字,删掉或换机构原图 |
| 命中差硬凑水文图 | --suggest 为空时提示人工补图,不凑数 |
| Pillow 缺失静默退回原图 | 改为明确报错,强制预装 |
| Windows urllib 走注册表代理抖动 | 上传脚本用 runner 强制直连(见 wechat-publisher) |
参考
references/wikimedia-api.md:Commons 搜索/下载/许可 API 速查(含 suggest 候选用法)references/wechat-image-limits.md:微信图片限制与发布对接要点