尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

Obsidian + Claude Code 搭自动化发布客户端:Playwright × 掘金/知乎/CSDN 的全链路踩坑实录

Obsidian + Claude Code 搭自动化发布客户端:Playwright × 掘金/知乎/CSDN 的全链路踩坑实录
📅 发布时间:2026/7/29 21:37:16

Obsidian + Claude Code 搭自动化发布客户端:Playwright × 掘金/知乎/CSDN 的全链路踩坑实录

AI工具人PM 的实战笔记:前几篇讲了掘金、知乎各自的自动化踩坑。这三篇合起来——我用 Obsidian + Playwright + Claude Code + Electron,从源码文件到三个平台一键发布,搭了一整套系统。这不是教程,是我的真实踩坑记录。


起因:三个平台的编辑器让我疯掉了

掘金是 CKEditor(直接往 DOM 里注入 HTML),知乎是 Draft.js(基于 React 的富文本编辑器,数据存在 Immutable.js 结构里,DOM 上看不到正文内容),CSDN 又是另一套编辑模式。

每次手动发一篇文章要开三个浏览器窗口,切换七八次——标题复制一次,内容复制三次(格式还不完全一样),标签一个个手选。

如果一天发一篇,一个月就是三十次这样的循环。但真正要命的是:

手动发的时候你不知道失败原因是什么。页面卡了?Cookie 过期了?网络超时了?你只能盯着转圈的那个按钮,不知道问题出在哪。

自动化是出路。但问题在于:怎么确保你的自动化真的跑通了?


架构:Obsidian 写 → Python 发 → Electron 看

┌─────────────────────────────────────────────────┐ │ Obsidian (Markdown 源文件) │ │ └── 待发布/ ← frontmatter: title, url, status │ │ └── 已发布/ ← 各平台归档 │ ├─────────────────────────────────────────────────┤ │ Python 后端 (vault-scripts/) │ │ ├── daily_publish.py ← 调度 + CLI 入口 │ │ ├── juejin.py ← 掘金 Playwright 引擎 │ │ ├── zhihu.py ← 知乎 Playwright 引擎 │ │ └── csdn.py ← CSDN Playwright 引擎 │ ├─────────────────────────────────────────────────┤ │ Electron 客户端 (pubhub) │ │ ├── main.js ← 主进程 + IPC handler │ │ ├── preload.js ← 安全桥接 │ │ ├── renderer/ ← Vue.js 前端 │ │ │ ├── index.html ← 表格列表 + 详情弹窗 │ │ │ ├── app.js ← 发布状态管理 │ │ │ └── style.css ← 暗色侧边栏 + 进度面板 │ │ └── data/ ← article_cache.json │ └─────────────────────────────────────────────────┘

核心设计原则: -Obsidian 是唯一的源。不用维护多份内容,frontmatter 字段统一管理 URL 和状态 -Python 负责重活。Playwright 控制 Chromium,模拟人在浏览器里的每一步操作 -Electron 提供反馈。CLI 脚本跑完后你知道发了吗——前端可视化看到每个平台的具体状态


IPC:主进程和渲染进程的对话

Electron 的安全模型规定渲染进程不能直接调用 Node API。所以需要一个中间层:

// preload.js — 安全的桥接 contextBridge.exposeInMainWorld('electronAPI', { scanArticles: () => ipcRenderer.invoke('scan-articles'), publishArticle: (title, platform) => ipcRenderer.invoke('publish-article', title, platform) }); // main.js — 实际执行 ipcMain.handle('publish-article', async (event, articleTitle, platform) => { const pythonScript = path.join(obsidianRoot, 'vault-scripts/daily_publish.py'); execFile('python', [pythonScript, '--once', '--title', articleTitle, '--platform', platform], ...); // stdout/stderr 解析为 JSON 返回给前端 });

关键点: -nodeIntegration: false+contextIsolation: true— 渲染进程沙箱化 ---title+--platform— 精准路由到目标文章和目标平台,不走全量队列 - 正则解析 stdout — Python 输出终端日志 → 前端能解析每个平台的状态


坑一:logger is not defined

CSDN 发布脚本的某一行用了logger.log(25, ...)打了一条 debug 日志,但文件头部没 import logging。结果整篇文章的发布流程中断,stderr 被吞掉,前端收到的错误信息是空白。

修复方式就是在文件开头加上:

import logging logger = logging.getLogger("csdn_publisher")

这个小 bug 卡了我一个小时——因为错误不在 daily_publish.py,不在 main.js,而在 csdn.py 内部。调试的时候需要一层层追 traceback。


坑二:Playwright inner_text(timeout=N) 新版已废弃

旧代码里写了opt.inner_text(timeout=100).strip()。在 Playwright 1.40+ 版本中,inner_text()不再接受 timeout 参数——这个参数在更早的版本已经移除了,只是之前的版本没有报错。

去掉 timeout 参数后,所有平台的自动化才真正跑通。这提醒我们:自动化脚本的生命周期比你想的长,依赖库更新时它也会跟着变老。


坑三:数据去重合并

同一个文章可能同时出现在待发布/和已发布/(比如刚发布还没从待发布目录移走)。扫描时需要按标题 key 去重并合并平台信息:

pending: [{zhihu: success}, {juejin: pending}] archive/csdn/: [{csdn: success}] 合并后: [{zhihu: success}, {juejin: pending}, {csdn: success}]

如果不去重,同一篇文章会在缓存里出现两条记录,前端显示的统计数据就会翻倍。


坑四:文件删除顺序

最危险的一步:发布成功后要删除待发布目录中的原文件。但如果删除过早(比如先删源文件再归档),一旦归档步骤失败,文章就永久丢失了。

正确的顺序: 1. 更新 frontmatter,写入各平台 URL 2. 拷贝到已发布目录(备份) 3. 确认拷贝成功 4. 才删除待发布目录中的文件


效果对比

维度手动客户端
单篇文章发布~15 分钟,三平台来回切换~10 秒自动完成
状态追踪打开三个网站逐个确认一行表格一目了然
失败排查不确定哪个环节出问题逐平台显示具体错误原因
重试操作从头再来一遍失败按钮可直接点重试
历史记录没有每篇文章的前后状态可追溯

总结:为什么一定要做这个客户端?

手动自动化都好用,但自动化的价值不在于快,而在于可见。

一个 Python 脚本就能搞定批量发布——我早就有了。但它的问题是:脚本跑完后你不知道结果。stdout 是文本,你需要 grep 才能看懂。

加了一个 Electron 客户端,把每个平台的发布状态、URL、时间戳、错误信息全部可视化呈现出来。这才是完整的闭环:

写 → 自动化发 → 看到结果 → 有问题可以重试 → 下次不再踩同样的坑

这个流程不是"省了多少分钟"的问题,而是让整个发布过程变成了可观测、可控制的系统。

对产品经理来说,这是一个把模糊过程变成清晰数据的典型案例——不是所有的东西都需要 GUI,但当你能看到每个环节的真实状态时,决策的质量会显著提升。

相关新闻

  • 5个必学ShaderGraph节点:unity-shadergraph-sandbox项目常用节点实战案例
  • Chocola均衡器终极教程:3步调出专业级音质体验
  • 电动机降压启动技术解析与应用实践

最新新闻

  • 破解海外用人难题:当地雇员与中国外派员工的合规管理与福利设计 - 2027品牌AI展
  • battleforthenet-widget常见问题解答:让你的网络中立活动更有效
  • 5分钟上手Templar:开发者必知的HTTP代理配置技巧
  • kafka基本命令
  • 第二周 题目练习2(stack综合 单调栈)牛客 14326. 14666. 15029
  • 东北的夏天已经长期维持在35摄氏度以上,这正常吗

日新闻

  • 金融舆情监测系统:多语言情感分析与实时可视化技术解析
  • QT C++调用Python异常处理:PyBind11实战与跨语言编程指南
  • A-47双麦回音消除模块:主次麦空间分布与差分连接对ENC性能的影响

周新闻

  • 大连理工大学与东京大学联手打造的“主动型AI助手“
  • 170.2026年国家级科研瓶颈:超精密单点金刚石切削(SPDT)光学表面生成
  • SongBloom:革命性歌曲生成框架深度解析——如何通过交织自回归与扩散模型创作完整音乐

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号