用 Playwright 实现博客一键发布到稀土掘金

用 Playwright 实现博客一键发布到稀土掘金

每次写完技术文章,手动发布到掘金总是让人头疼 ------ 复制标题、粘贴正文、选分类、加标签、上传封面......重复劳动,能省就省。

于是我花了半天写了一个自动化发布工具,用 Python + Playwright 模拟浏览器操作,把整个发布流程跑通了。

核心思路

直接调用掘金官方 API 发布文章?理论上可行,但掘金没有公开的写作 API,逆向内部接口风险高、不稳定。

更靠谱的方案是 浏览器自动化 ------ 用 Playwright 驱动真实浏览器,模拟用户的每一步操作:点击按钮、粘贴内容、选标签、点发布。

这样的好处是:

  • 不依赖接口,不怕平台改动 API
  • 跟正常用户操作完全一致,不触发风控
  • 调试直观,能实时看到浏览器在干什么

技术选型

工具 作用
Playwright 浏览器自动化(替代 Selenium,更现代)
pyperclip 系统剪贴板操作
PyYAML 解析 Markdown front matter
requests 下载封面图片

选 Playwright 而不是 Selenium 的原因:

  • 自带浏览器,不用手动下载 chromedriver 并对齐版本
  • API 更简洁,等待元素、截图等操作都更自然
  • 支持 storage_state,可以保存登录 cookie,下次直接复用

一个关键坑:CodeMirror 编辑器

掘金的文章编辑器用的是 CodeMirror,这是个富文本编辑器,它的特点是 HTML 内容随输入动态变化。

所以你不能element.fill()send_keys() 直接输入文章内容 ------ 内容不会进到编辑器里。

正确做法是用 系统剪贴板粘贴

python 复制代码
import pyperclip
import sys

# 把内容复制到剪贴板
pyperclip.copy(file_content)

# 点击编辑区域
content_element = page.locator('//div[@class="CodeMirror-code"]//span[@role="presentation"]')
content_element.click()

# 模拟 Ctrl+V 粘贴
if sys.platform == 'darwin':
    page.keyboard.press('Meta+v')
else:
    page.keyboard.press('Control+v')

粘贴后,掘金会自动解析 Markdown 并重新上传其中的图片。这个过程需要时间,建议 time.sleep(15) 等待图片上传完成。

Playwright 的 storage_state 功能可以把浏览器的 cookie 和 localStorage 一起保存到本地 JSON 文件,下次启动时直接加载:

python 复制代码
# 保存登录状态
storage = context.storage_state()
with open('storage/juejin_storage.json', 'w') as f:
    json.dump(storage, f)

# 下次启动时复用
context = browser.new_context(
    storage_state='storage/juejin_storage.json'
)

这样只需要手动登录一次,之后每次发布都自动复用登录态,无需重复扫码。

从 Markdown front matter 读取元数据

文章用 YAML front matter 格式管理元数据:

markdown 复制代码
---
title: 文章标题
description: 文章摘要
image: https://example.com/cover.jpg
tags:
  - Python
  - 自动化
---

# 正文开始

解析代码:

python 复制代码
import re
import yaml

def parse_front_matter(content: str) -> dict:
    match = re.match(r'^---\s*\n(.*?)\n---\s*\n', content, re.DOTALL)
    if match:
        return yaml.safe_load(match.group(1)) or {}
    return {}

封面图片从 image 字段读取,先下载到本地,再通过 file input 上传:

python 复制代码
file_input = page.locator("//input[@type='file']")
file_input.set_input_files(local_image_path)

完整发布流程

整个发布流程按顺序:

  1. 加载 cookie → 自动登录
  2. 打开掘金创作者页面https://juejin.cn/creator/home
  3. 点击写文章.send-button
  4. 等待编辑器加载 → 检测标题 input 出现
  5. 填写标题//input[@placeholder="输入文章标题..."]
  6. 粘贴正文 → 剪贴板 + Ctrl+V
  7. 等待图片上传 → sleep 15s
  8. 点击发布按钮 → 打开发布设置面板
  9. 设置分类 → 点击对应分类按钮
  10. 添加标签 → 剪贴板粘贴 + 选下拉框
  11. 上传封面 → file input
  12. 设置摘要 → textarea 填充
  13. 确认发布 → 点击"确定并发布"

使用方法

第一步:安装依赖

bash 复制代码
pip install playwright pyyaml pyperclip requests
playwright install chromium

第二步:登录(只需一次)

bash 复制代码
python3 login.py juejin

浏览器会打开掘金,扫码登录后按 Enter,cookie 自动保存。

第三步:发布文章

bash 复制代码
# 不自动发布,人工 review
python3 publish.py --platform juejin --content article.md --no-publish

# 全自动发布
python3 publish.py --platform juejin --content article.md

扩展性

整个架构设计上很容易扩展新平台:

复制代码
publisher/
├── juejin_publisher.py   ✅ 稀土掘金
├── zhihu_publisher.py    🟡 知乎(TODO)
└── csdn_publisher.py     🟡 CSDN(TODO)

每个平台只需实现一个 xxx_publisher(page, content_file) 函数,主流程自动调用。后续会陆续补上知乎和 CSDN 的支持。

小结

用 Playwright 自动化发布博客的核心就两点:

  1. Cookie 持久化 ------ 一次登录,长期复用
  2. 剪贴板粘贴 ------ 应对富文本编辑器(CodeMirror)

比 Selenium 更轻量,比逆向 API 更稳定。如果你也在多个平台同步发布文章,不妨试试这个思路。


项目地址稍后整理后会放出,欢迎 star ⭐

相关推荐
曲幽2 小时前
FastAPI分布式系统实战:拆解分布式系统中常见问题及解决方案
redis·python·fastapi·web·httpx·lock·asyncio
孟健17 小时前
Karpathy 用 200 行纯 Python 从零实现 GPT:代码逐行解析
python
码路飞19 小时前
写了个 AI 聊天页面,被 5 种流式格式折腾了一整天 😭
javascript·python
曲幽21 小时前
FastAPI压力测试实战:Locust模拟真实用户并发及优化建议
python·fastapi·web·locust·asyncio·test·uvicorn·workers
敏编程1 天前
一天一个Python库:jsonschema - JSON 数据验证利器
python
前端付豪1 天前
LangChain记忆:通过Memory记住上次的对话细节
人工智能·python·langchain
databook1 天前
ManimCE v0.20.1 发布:LaTeX 渲染修复与动画稳定性提升
python·动效
花酒锄作田2 天前
使用 pkgutil 实现动态插件系统
python
前端付豪2 天前
LangChain链 写一篇完美推文?用SequencialChain链接不同的组件
人工智能·python·langchain