Skip to content
Ahri-qwqPublic

About

微信公众号文章 → LLM 翻译 → 审核 → 博客格式 全自动workflow

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

26 Commits

Folders and files

Repository files navigation

微信公众号文章 → 博客格式 全自动流水线

一站式工具:下载微信文章 → LLM 翻译 → 审核 → OSS 上传图片 → 格式转换 → 输出 deepmodeling/blog 兼容的 Markdown。

🎯 功能

  • 下载微信公众号文章(内容 + 图片)
  • 装饰图自动过滤:基于感知哈希(pHash)识别并过滤模板装饰图
  • 智能图片重编号:按正文出现顺序统一重编号为 pic1/pic2/...
  • 多 LLM 翻译(支持 Qwen / DeepSeek,可随时切换对比)
  • LLM 自动审核翻译质量(支持双模型交叉审查)
  • OSS 图片上传:自动上传到阿里云 OSS 并替换为 HTTPS 地址
  • LaTeX 公式保留:下载器从微信 HTML 提取 LaTeX 源码,转换器归一化为 $...$ / $$...$$,交由站点 MathJax 渲染
  • 自动转换为博客格式(frontmatter + <center><img> + <!-- more -->)
  • LLM 自动分类(categories)
  • 一条命令串起下载、翻译审核、OSS 上传、博客格式转换、GitHub PR 和可选的领英文案生成
  • 领英文案:Step 7 从转换后的博客稿生成动态文案,保存到文章目录的 linkedin/,审核后手工发布
  • GitHub PR 自动提交:通过 gh CLI 自动创建 PR 到目标仓库(branch → push → PR,不动 master)
  • 项目与目标仓库隔离:目标仓库缓存在项目外部,互不污染
  • 容错设计:任意步骤出错时提示重试/跳过,不阻塞流水线

📁 项目结构

translate/
├── config.yaml              # LLM + OSS + 审查 + GitHub 多合一配置(不入库)
├── config.yaml.example      # 配置文件模板(可入库,供新用户参考)
├── .gitignore               # 排除敏感配置和输出文件
├── models/
│   └── decorative_hashes.json # 装饰图哈希库(由 --build 生成)
├── requirements.txt         # Python 依赖
├── src/
│   ├── main.py              # 主入口(交互 / 命令行 / 批量)
│   ├── downloader.py        # 下载 + 图片重编号 + 装饰图过滤
│   ├── translator.py        # LLM 翻译 + 审核 + 交叉审查
│   ├── converter.py         # 格式转换 + 公式转换 + LLM 分类
│   ├── oss_uploader.py      # 阿里云 OSS 图片上传
│   ├── github_uploader.py   # GitHub PR 自动提交
│   ├── linkedin_writer.py   # 生成领英动态文案
│   ├── decorative_filter.py # 装饰图 pHash 过滤器
│   └── utils.py             # 共享工具函数
├── data/
│   ├── decorative_samples/     # 装饰图样本(手动放入,用于构建哈希库)
│   ├── OSS/oss工具.md         # 阿里云 OSS 工具文档索引
│   ├── Todo.md                 # 任务列表
│   ├── formula-handling.md     # 公式处理记录(格式 / 下载器 / 转换阶段)
│   ├── 报告/                   # 各轮缺陷复盘与修复报告
│   └── blog/source/_posts/     # 参考博客源文件(用于格式对齐)
└── output/                  # 输出目录
    └── article_{时间戳}/
        ├── {标题}_zh.md           # 中文原文(含元数据块)
        ├── {标题}_en.md           # 英文翻译(含翻译元数据)
        ├── {标题}_review.md       # 审核报告(有问题时生成)
        ├── {标题}.images_map.txt  # 图片 URL 映射(上传后更新为 OSS 地址)
        ├── images/                # 下载的图片(pic1.png, pic2.png, ...)
        └── blog_output/
            └── {CATEGORY}_{YYYY}_{MM}_{DD}.md  # 最终博客文件

🚀 使用方法

交互模式(推荐)

python src/main.py

然后按提示选择 LLM 和模型,输入文章链接即可全自动完成。

可用 LLM 提供商:
  [1] qwen         当前默认: qwen3.7-max
  [2] deepseek     当前默认: deepseek-v4-pro
  [Enter] 退出

选择 LLM: 2

deepseek 可用模型:
  [1] deepseek-v4-pro ★默认
  [2] deepseek-v4-flash
  [3] deepseek-v4.1
  [4] deepseek-chat
  [5] deepseek-reasoner
  [Enter] 使用默认

模型: 2

🧹 装饰图过滤
是否更新装饰图哈希库?[1] 更新  [Enter] 跳过:

微信文章链接 [回车退出]: https://mp.weixin.qq.com/s/xxx

命令行模式

# 单篇全自动处理
python src/main.py --url "https://mp.weixin.qq.com/s/xxx"

# 指定 LLM 和模型
python src/main.py --url "..." --llm deepseek --model deepseek-v4-pro

# 仅下载(不翻译、不转换,但会上传 OSS 如果已配置)
python src/main.py --url "..." --download-only

# 批量处理(从文件读取 URL)
python src/main.py --file urls.txt --llm deepseek

# 单独运行格式转换
python src/converter.py --dir output/article_xxx --llm deepseek

# 单独运行 OSS 上传
python src/oss_uploader.py --dir output/article_xxx

# 单独运行 GitHub 上传
python src/github_uploader.py --dir output/article_xxx
python src/github_uploader.py --file output/article_xxx/blog_output/xxx.md

# 构建装饰图哈希库
python src/decorative_filter.py --build

批量处理文件格式

创建 urls.txt:

https://mp.weixin.qq.com/s/xxx1
https://mp.weixin.qq.com/s/xxx2
https://mp.weixin.qq.com/s/xxx3

装饰图过滤

微信公众号模板装饰图(顶部横幅、分割线、底部二维码等)是同一批固定图片反复出现。本项目用感知哈希(pHash)自动识别并过滤。

初始化(一次性):

# 1. 将标记好的装饰图放入 data/decorative_samples/(平铺,无需分类子目录)
# 2. 构建哈希库
python src/decorative_filter.py --build

日常维护:发现新装饰图时,扔进 data/decorative_samples/ 重新 --build 即可。

过滤行为:命中图片自动移至 images/_filtered/(可恢复),markdown 引用同步删除。哈希库不存在时静默跳过,不影响下载。

📦 安装依赖

Python 依赖

pip install -r requirements.txt

依赖:

  • requests — HTTP 请求
  • beautifulsoup4 — HTML 解析
  • markdownify — HTML 转 Markdown
  • openai — LLM API 调用(兼容 OpenAI / DeepSeek / DashScope)
  • pyyaml — 配置文件解析
  • imagehash — 感知哈希(装饰图过滤)
  • Pillow — 图片处理

外部工具(可选)

  • ossutil 2.0 — 阿里云 OSS 命令行工具,用于图片上传。如不需要 OSS 上传功能可不安装。
  • GitHub CLI (gh) — 用于自动创建 PR 上传博客。如不需要 GitHub 上传功能可不安装。
    winget install GitHub.cli    # Windows
    brew install gh              # macOS
    安装后登录:gh auth login

⚙️ 配置

新用户第一步:复制模板文件并填入实际值。

copy config.yaml.example config.yaml   # Windows
cp config.yaml.example config.yaml     # macOS / Linux

然后编辑 config.yaml,填入各服务的 API Key 和 AccessKey。

config.yaml 已加入 .gitignore,不会被提交到 Git 仓库。


config.yaml 包含四部分:LLM 提供商、OSS 上传、翻译审查、GitHub 上传。

LLM 提供商

llm:
  default: "qwen"       # 默认提供商(可通过 --llm 参数覆盖)
  providers:
    qwen:
      api_key: "sk-xxx"
      base_url: "https://dashscope.aliyuncs.com/compatible-mode/v1"
      model_name: "qwen3.7-max"
    deepseek:
      api_key: "sk-xxx"
      base_url: "https://api.deepseek.com"
      model_name: "deepseek-v4-pro"

可用模型(运行时选择):

提供商 模型
Qwen qwen3.7-max, qwen3.7-plus, qwen3.6-flash, qwen-max
DeepSeek deepseek-v4-pro, deepseek-v4-flash, deepseek-v4.1, deepseek-chat, deepseek-reasoner

注意:deepseek-chat 和 deepseek-reasoner 将于 2026/07/24 弃用,建议迁移至 deepseek-v4-pro / deepseek-v4-flash。

OSS 图片上传

oss:
  access_key_id: "LTAI5txxx"              # 阿里云 AccessKey ID(必填)
  access_key_secret: "xxx"                # 阿里云 AccessKey Secret(必填)
  bucket: "dp-public"                     # OSS Bucket 名称
  endpoint: "oss-cn-beijing.aliyuncs.com" # OSS Endpoint
  region: "cn-beijing"                    # Bucket 所在地域
  path_prefix: "community/Blog Files"     # OSS 上传路径前缀

提示:如果未配置 OSS(AK 为空),流水线会自动跳过上传步骤,使用原始微信 CDN URL。

AK 轮换记录

这对 AccessKey 由运维(陈少杰)签发,对应 bucket dp-public 下 community/ 前缀的读写权限。AK 会周期性轮换,旧 AK 被回收后流水线会在图片上传环节失败。

日期 事件 说明
2026-07-14 首次签发 运维通过飞书下发,用于替代手工传图
2026-11-12 轮换 换入新 AK;旧 AK 实测已失效(EC: 0002-00000903,AccessKey ID 不存在或已禁用)。新 AK 读写均已验证

轮换时要做的事(只有 config.yaml 一处,该文件已被 .gitignore 排除):

  1. 停掉正在跑的流水线任务,避免上传到一半切凭证
  2. 改 config.yaml 的 oss.access_key_id / oss.access_key_secret
  3. 验证读:ossutil ls oss://dp-public/community/ --region cn-beijing 应返回对象列表
  4. 验证写:传一张小图到临时前缀,确认后删掉
  5. 更新上表的轮换记录
  6. 通知运维旧 AK 可以回收

故障特征:图片上传全部失败且报 EC: 0002-00000903,优先怀疑 AK 已轮换, 而不是代码或网络问题。

翻译审查

review:
  cross_review: true          # 是否启用双模型交叉审查
  second_reviewer: "qwen"     # 第二个审查模型(引用 llm.providers 中的名称)
  max_revise_rounds: 1        # 最大修改轮次(审查未通过时自动修改)

交叉审查流程:当 cross_review: true 时,翻译完成后会由主模型 + 第二模型分别独立审查,合并两份报告(取较低分数、合并问题列表)。审查未通过时自动调用 LLM 修改译文。

GitHub 博客上传

github:
  repo: "deepmodeling/blog"         # 目标仓库
  branch: "master"                  # 目标分支(PR base)
  cache_dir: ""                     # 本地缓存目录(留空则默认 ../blog-cache)

工作流程:拉取最新 master → 创建 post-{CATEGORY}_{YYYY}_{MM}_{DD} 分支 → 复制博客文件 → 推送 → 创建 PR。绝不直接操作 master 分支。

仓库隔离:目标仓库 clone 到项目外部的缓存目录(默认 ../blog-cache),与翻译项目仓库互不影响。

前置条件:需安装 GitHub CLI 并登录。

winget install GitHub.cli   # 安装
gh auth login               # 登录

提示:如果未配置 GitHub 段或 gh 不可用,流水线会自动跳过上传步骤。

📝 处理流程

[Step 1/7] 下载文章
    ├── 提取正文、标题、公式
    ├── 智能图片重编号(按出现顺序 pic1/pic2/...)
    ├── 装饰图 pHash 过滤(命中图片移至 _filtered/)
    ├── 跳过音视频内容并标注
    └── 生成中文 Markdown + images_map.txt

[Step 2/7] 交互确认 → LLM 翻译 + 审核
    ├── 询问用户是否翻译(可跳过,仅保留中文版)
    ├── 中文 → 英文翻译(保留公式、图片、Markdown 语法)
    ├── LLM 审核(漏译 / 术语 / 格式)
    ├── 交叉审查(可选):双模型独立审查,合并报告
    └── 未通过时自动修改译文(最多 N 轮,可配置)

[Step 3/7] 保存文件
    ├── {标题}_zh.md — 中文原文
    ├── {标题}_en.md — 英文译文(含翻译元数据头)
    ├── {标题}_review.md — 审核报告
    ├── {标题}.images_map.txt — 图片 URL 映射
    └── images/ — 下载的正文图片

[Step 4/7] OSS 上传(可选)
    ├── 上传 images/ 中所有图片到 OSS
    ├── 更新 images_map.txt 为 OSS HTTPS 地址
    └── 上传失败时自动回退到原始微信 CDN URL

[Step 5/7] 格式转换 → 博客格式
    ├── LLM 自动分类(categories)
    ├── 清理翻译元数据块(> Source, > Translated by 等)
    ├── LaTeX 公式归一化(\(...\) → $...$,交由 MathJax 渲染)
    ├── 图片语法转换(![](local) → <center><img src=url /></center>)
    ├── 图N → Figure N 自动翻译
    ├── 图片间加粗文本 → ## 二级标题
    ├── 自动插入 <!-- more -->(第一段落后)
    ├── 自动检测 mathjax: true(含公式时写入,在归一化前检测以确保准确)
    └── 文件命名:{CATEGORY}_{YYYY}_{MM}_{DD}.md

[Step 6/7] 上传 GitHub → PR
    ├── 检查 gh CLI 可用 & 已登录
    ├── 同步本地缓存仓库(git pull origin master)
    ├── 创建分支 post-{CATEGORY}_{YYYY}_{MM}_{DD}
    ├── 复制 blog_output/*.md → source/_posts/
    ├── git commit + git push
    └── gh pr create → 返回 PR 链接

[Step 7/7] 生成领英动态文案(可跳过)
    ├── 从转换后的博客 Markdown 生成纯文本
    └── 保存到文章目录的 linkedin/,由人工审核并发布

2026-11-10 修复了标题漏译的兜底路径。验证方式和原因见 标题漏译修复报告。

📊 输出格式

英文翻译文件(_en.md)

# Translated English Title

> Source: https://mp.weixin.qq.com/s/xxx
> Original title: 中文原标题
> Translated by deepseek
> Quality score: 85/100 (PASSED)

---

Body content with images and formulas...

博客 Markdown(最终产物)

---
title: "DP Can Also Do This? Deep Learning Potential Framework..."
date: 2026-07-14
categories:
- DeePMD-kit
---

<center><img src=https://oss-url/pic1.png pic_center width="100%" height="100%" /></center>

Body content...

<!-- more -->

## Section Title

More content...

<center><img src=https://oss-url/pic2.png pic_center width="100%" height="100%" /></center>

🧪 测试

# 测试翻译模块(使用内置示例文本,无需网络)
python src/translator.py

# 测试下载模块(需提供真实微信文章 URL)
python src/downloader.py

# 测试格式转换(需提供已有输出目录)
python src/converter.py --dir output/article_xxx

# 测试 OSS 上传(需提供已有输出目录)
python src/oss_uploader.py --dir output/article_xxx

📋 待完成

  • 上传 GitHub 脚本
  • Markdown 表格格式自动修复(微信表格 → 标准 Markdown 表格)
  • 公式提取增强:CSS 模拟下标格式(vertical-align:sub)的识别与 LaTeX 还原
  • 公式提取增强:公式图片的 OCR/alt-text 识别

Created: 2026-03-31 | Updated: 2026-07-15

About

微信公众号文章 → LLM 翻译 → 审核 → 博客格式 全自动workflow

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages