DEV Community

wxfwxf911
wxfwxf911

Posted on

开源项目从 0 到 1:我用 2 周业余时间搭建了多平台发布系统

开源项目从 0 到 1:我是怎么用 2 周业余时间搭建多平台发布系统的

起因:一个周三晚上的崩溃

故事开始于一个普通的周三晚上。

22:00,写完了一篇 Python 教程。22:35,还在复制粘贴第 6 个平台。

当时心里想的是:「我写了 40 分钟文章,为什么还要花 30 分钟发布?」

作为一个程序员的本能反应——这个问题应该用代码解决。

Day 1-2:技术选型

动手之前花了两天调研。核心问题是:怎么跟 9 个平台对话?

经过调研发现,平台分三类:

类型 代表 方案
有公开 API 掘金、CSDN、Dev.to HTTP 请求直接调
有半公开 API 知乎、博客园 需要逆向签名(x-zse-96、X-Ca)
没有 API 小红书、抖音 只能 Playwright 浏览器模拟

技术栈决策:

后端: Python + FastAPI
  - 选 Python 因为 Playwright 的 Python 绑定最成熟
  - 选 FastAPI 因为异步支持好,自带文档

前端: 原生 HTML/CSS/JS
  - 不需要 React/Vue。一个管理后台而已,原生 JS 完全够用
  - 零 npm 依赖,部署简单

数据库: SQLite
  - 单文件,不需要装 MySQL/PostgreSQL
  - 个人工具,并发不是问题

浏览器插件: Chrome Extension Manifest V3
  - 一键提取 Cookie,用户不用手动 F12
Enter fullscreen mode Exit fullscreen mode

不做的事情:

  • ❌ 不用 Docker(增加复杂度,个人部署不需要)
  • ❌ 不用 Redis(SQLite 足够)
  • ❌ 不用前端框架(过度设计)

Day 3-5:搭建骨架

先搭最小可用版本:一个 API + 一个页面 + 一个平台

选掘金作为第一个平台——它有公开 API,最简单。

# 核心抽象:每个平台一个 Adapter
class BasePlatform:
    async def publish(self, title, content, tags, credentials) -> PublishResult:
        raise NotImplementedError

    async def fetch_stats(self, post_id, credentials) -> StatsResult:
        raise NotImplementedError
Enter fullscreen mode Exit fullscreen mode

这个阶段的关键决策:

  1. 策略模式:每个平台是一个独立的 Adapter 类,新增平台不改核心逻辑
  2. 异步优先:所有网络请求用 async/await,发布 9 个平台可以并发
  3. 失败隔离:一个平台失败不影响其他平台

骨架搭完后,掘金能发了。但只有一个平台没意义——得把所有平台都接上。

Day 6-10:攻克硬骨头

知乎:逆向 x-zse-96 签名

知乎的 API 要求每个请求带一个 x-zse-96 签名头。签名的生成逻辑藏在知乎前端的混淆 JS 里。

花了两个晚上逆向:原来是 MD5(特定参数 + d_c0 Cookie) → AES-CBC 加密 → 拼接前缀

def _make_x_zse_96(url: str, d_c0: str) -> str:
    source = f"101_3_3.0+/api/v4/{url}+{d_c0}"
    md5_hash = hashlib.md5(source.encode()).hexdigest()
    # ... AES-CBC 加密 ...
    return "2.0_" + encrypted.hex()
Enter fullscreen mode Exit fullscreen mode

搞定的那一刻,知乎文章秒发——那种感觉比写完代码还爽。

CSDN:阿里云网关签名

CSDN 用的是阿里云 API 网关的 HMAC-SHA256 签名方案。文档是中文的,但签名串的格式写得很隐晦——分隔符必须是 \n,不能是空格。这个细节浪费了我两个小时。

博客园:2002 年的 XML-RPC

博客园的 API 是 MetaWeblog XML-RPC——一个 2002 年的协议。Python 标准库自带的 xmlrpc.client 直接用。但有个坑:分类里不加 [Markdown],文章就会被当 HTML 解析。

小红书:Playwright 兜底

小红书没有公开 API,只能上 Playwright。但每次启动浏览器要 2-3 秒。优化手段:

  • Cookie 持久化,跳过登录
  • 先通过 API 拿到图片上传地址,只让 Playwright 做最后的表单提交
  • 在 Linux 服务器上用 Xvfb 虚拟显示

Day 11-14:打磨产品

核心功能跑通后,开始打磨:

  1. 数据看板:每个平台的阅读/点赞/评论自动汇总,不用挨个登录后台
  2. 浏览器插件:一键提取 Cookie,告别手动 F12
  3. 错误处理:发布失败自动重试,详细的错误日志
  4. 前端:深紫渐变配色,告别 Bootstrap 蓝

踩过的坑(诚实版)

  1. 思否的雷池 WAF(HTTP 468)——连 Playwright headful 模式都过不了,目前无解
  2. CSDN 只能发草稿——API 发布只有 status=2(草稿),要手动去后台点「发布」还要微信扫码
  3. 知乎 content/daily API 需要「致知计划」权限——浪费半天调试,最后换了 creations/v2/all
  4. Dev.to 反垃圾机制——标题 5 分钟内不能重复,包括不同文章

数据和反馈

两周开发,目前:

  • 9 个平台接入
  • 15 篇文章发布
  • 累计 143 阅读(掘金 23、知乎 50、CSDN 70)

数字不大,但对于一个刚上线两天的开源项目来说,是个不错的开始。

下一步

  • Docker 一键部署
  • AI 内容改写(根据平台风格自动调整语气)
  • 海外平台支持(Medium、Hashnode)
  • 定时发布

最后

这个项目让我体会到一件事:程序员最好的副业,是解决自己的问题

你自己就是用户,知道痛点在哪,不需要做用户调研。用着顺手了,开源出来——自然有人跟你一样需要它。

如果你也在维护多个平台,或者想看看 Python + Playwright 怎么搞定 9 个平台的自动化:

👉 GitHub: https://github.com/wxfwxf911/polypost

Star ⭐ 是我持续维护的动力。如果有什么平台想让我支持,提 Issue。


标签:开源, Python, Playwright, 自动化, 独立开发

Top comments (0)