用代码做自媒体(一):Python 调用博客园(cnblogs) MetaWeblog API 自动发布 Markdown 文章
用一段纯标准库的 Python 脚本,把本地 Markdown 通过博客园的 MetaWeblog API(XML-RPC) 一键发布、更新、查询,告别网页后台复制粘贴。下面是可直接照抄的完整步骤和脚本。
环境
- Python 3.6+(只用标准库
xmlrpc.client,无需pip install) - 一个博客园账号(接口端点形如
https://rpc.cnblogs.com/metaweblog/<博客名>) - 操作系统无关(Linux / macOS / Windows 均可)
步骤 1:后台启用 MetaWeblog 并拿令牌
MetaWeblog 默认关闭,不开直接调用会报 Fault 403: 您的博客已禁用 MetaWeblogApi。
- 打开
https://i.cnblogs.com/settings#enableServiceAccess - 勾选「博客客户端访问」并保存
- 复制页面上的访问令牌(Token)——注意它不是登录密码,且启用时可能被重新生成,务必用最新的
- 同一页面能看到你的接口地址:
https://rpc.cnblogs.com/metaweblog/<你的博客名>
步骤 2:保存发布脚本
把下面的脚本存为 cnblogs_publish.py,改掉 ENDPOINT 里的博客名:
#!/usr/bin/env python3
import os, sys, argparse, xmlrpc.client
from datetime import datetime
ENDPOINT = "https://rpc.cnblogs.com/metaweblog/<你的博客名>"
BLOG_ID = "blog" # 博客园下此值不影响结果
def server():
return xmlrpc.client.ServerProxy(ENDPOINT, allow_none=True)
def creds():
return os.environ["CNBLOGS_USER"], os.environ["CNBLOGS_TOKEN"]
def list_posts(n):
u, t = creds()
for p in server().metaWeblog.getRecentPosts(BLOG_ID, u, t, n):
print(p["postid"], p["dateCreated"], p["title"])
def publish(md, title, cats, tags, postid, draft):
u, t = creds()
content = open(md, encoding="utf-8").read()
cats = [c.strip() for c in cats.split(",")] if cats else []
if "[Markdown]" not in cats: # 见步骤 6 的坑
cats.insert(0, "[Markdown]")
post = {"title": title, "description": content,
"dateCreated": datetime.now(), "categories": cats,
"mt_keywords": tags or ""}
s, flag = server(), not draft # flag: True=公开 False=草稿
if postid:
s.metaWeblog.editPost(postid, u, t, post, flag); print("updated", postid)
else:
print("created", s.metaWeblog.newPost(BLOG_ID, u, t, post, flag))
if __name__ == "__main__":
ap = argparse.ArgumentParser()
ap.add_argument("md", nargs="?"); ap.add_argument("--title")
ap.add_argument("--cats"); ap.add_argument("--tags"); ap.add_argument("--postid")
ap.add_argument("--draft", action="store_true"); ap.add_argument("--list", type=int)
a = ap.parse_args()
if a.list: list_posts(a.list)
else: publish(a.md, a.title, a.cats, a.tags, a.postid, a.draft)
步骤 3:配置凭证
凭证从环境变量读取,别硬编码进脚本:
export CNBLOGS_USER=你的博客名
export CNBLOGS_TOKEN=你的访问令牌
步骤 4:验证连通
先列出最近文章,能打印出来就说明打通了:
python3 cnblogs_publish.py --list 5
输出示例:
20187928 20260527T16:27:00 如何通过博客园的 MetaWeblog API 发布文章
19806404 20260401T13:17:00 PostgreSQL 备份表结构和数据
19521376 20260123T11:45:00 监控指标
步骤 5:发布文章(先草稿,确认后公开)
先发草稿,在后台预览渲染无误,再带 postid 转公开:
# 发草稿
python3 cnblogs_publish.py post.md --title "我的标题" \
--cats "[随笔分类]Python" --tags "python,自动化" --draft
# 确认后转公开(用上一步返回的 postid,去掉 --draft)
python3 cnblogs_publish.py post.md --title "我的标题" \
--cats "[随笔分类]Python" --tags "python,自动化" --postid 上一步的ID
步骤 6:避开三个坑
Fault 403: 已禁用 MetaWeblogApi:后台开关没开或令牌过期,回到步骤 1。- 格式全乱:
categories必须含[Markdown],否则博客园按 HTML 解析正文。脚本已自动插入。 - 分类没生效/建出重复分类:
--cats的名称要带[随笔分类]前缀且与后台一字不差;不确定先getCategories查。
快速参考
接口端点 https://rpc.cnblogs.com/metaweblog/<博客名>
启用页面 https://i.cnblogs.com/settings#enableServiceAccess
凭证 export CNBLOGS_USER / CNBLOGS_TOKEN(Token 非登录密码)
列文章 python3 cnblogs_publish.py --list N
发草稿 ... --draft
转公开 ... --postid <ID>
| 方法 | 作用 |
|---|---|
metaWeblog.newPost |
新建(末参 True 公开 / False 草稿) |
metaWeblog.editPost |
更新(带 postid) |
metaWeblog.getRecentPosts |
列最近文章 |
metaWeblog.getCategories |
取分类(含 [Markdown] 等标志) |
blogger.deletePost |
删除 |
三条铁律:正文 Markdown 必带 [Markdown];分类名带 [随笔分类] 前缀且一字不差;先草稿预览再公开。

浙公网安备 33010602011771号