使用博客比较少,一则是文笔有限,怕写出的东西狗屁不通,有碍观瞻, 二则是懒,很讨厌要登陆到网站上写东西,也没有那么多时间(借口)。我的最喜欢用于记录的工具是Zim https://zim-wiki.org/ ,记录东西超级方便,惋惜只支持PC版本, 记录的东西能够处处为MarkDown 格式,很是方便(你如今看到的这篇就是用Zim写的)。html
无心间看到Vs Code上有博客园的插件,做为程序员,顺手google/百度了一下,原来通用博客都支持使用metaweblog API来访问,还支持直接发布markdown 格式,简直不要太好。 找了找2年前注册的博客源帐号,用来测试一下。python
发挥典型中国程序员的拿来主义精神,通过goolgle/百度一番搜索,参考如下文档进行API测试,在此表示感谢!!
http://www.javashuo.com/article/p-cwrmfhpa-ch.html
https://github.com/1024th/cnblogs_githookgit
在博客设置最的最末端,有MetaWeblog 的访问地址连接
点击进入页面,有metaweblog API 的详细说明
具体内容不赘述了。程序员
使用python3 进行API测试,直接上代码:
```python
#encoding = utf-8
#!/bin/sh python3github
import xmlrpc.client as xmlrpclib import json ''' 配置字典: type | description(example) str | metaWeblog url, 博客设置中有('https://rpc.cnblogs.com/metaweblog/1024th') str | appkey, Blog地址名('1024th') str | blogid, 这个无需手动输入,经过getUsersBlogs获得 str | usr, 登陆用户名 str | passwd, 登陆密码 str | rootpath, 博文存放根路径(添加git管理) ''' ''' POST: dateTime dateCreated - Required when posting. string description - Required when posting. string title - Required when posting. array of string categories (optional) struct Enclosure enclosure (optional) string link (optional) string permalink (optional) any postid (optional) struct Source source (optional) string userid (optional) any mt_allow_comments (optional) any mt_allow_pings (optional) any mt_convert_breaks (optional) string mt_text_more (optional) string mt_excerpt (optional) string mt_keywords (optional) string wp_slug (optional) ''' class MetablogClient(): def __init__(self, configpath): ''' @configpath: 指定配置文件路径 ''' self._configpath = configpath self._config = None self._server = None self._mwb = None def createConfig(self): ''' 建立配置 ''' while True: cfg = {} for item in [("url", "metaWeblog url, 博客设置中有\ ('https://rpc.cnblogs.com/metaweblog/blogaddress')"), ("appkey", "Blog地址名('blogaddress')"), ("usr", "登陆用户名"), ("passwd", "登陆密码"), ("rootpath", "博文本地存储根路径")]: cfg[item[0]] = input("输入"+item[1]) try: server = xmlrpclib.ServerProxy(cfg["url"]) userInfo = server.blogger.getUsersBlogs( cfg["appkey"], cfg["usr"], cfg["passwd"]) print(userInfo[0]) # {'blogid': 'xxx', 'url': 'xxx', 'blogName': 'xxx'} cfg["blogid"] = userInfo[0]["blogid"] break except: print("发生错误!") with open(self._configpath, "w", encoding="utf-8") as f: json.dump(cfg, f, indent=4, ensure_ascii=False) def existConfig(self): ''' 返回配置是否存在 ''' try: with open(self._configpath, "r", encoding="utf-8") as f: try: cfg = json.load(f) if cfg == {}: return False else: return True except json.decoder.JSONDecodeError: # 文件为空 return False except: with open(self._configpath, "w", encoding="utf-8") as f: json.dump({}, f) return False def readConfig(self): ''' 读取配置 ''' if not self.existConfig(): self.createConfig() with open(self._configpath, "r", encoding="utf-8") as f: self._config = json.load(f) self._server = xmlrpclib.ServerProxy(self._config["url"]) self._mwb = self._server.metaWeblog def getUsersBlogs(self): ''' 获取博客信息 @return: { string blogid string url string blogName } ''' userInfo = self._server.blogger.getUsersBlogs(self._config["appkey"], self._config["usr"], self._config["passwd"]) return userInfo def getRecentPosts(self, num): ''' 读取最近的博文信息 ''' return self._mwb.getRecentPosts(self._config["blogid"], self._config["usr"], self._config["passwd"], num) def newPost(self, post, publish): ''' 发布新博文 @post: 发布内容 @publish: 是否公开 ''' while True: try: postid = self._mwb.newPost(self._config['blogid'], self._config['usr'], self._config['passwd'], post, publish) break except: time.sleep(5) return postid def editPost(self, postid, post, publish): ''' 更新已存在的博文 @postid: 已存在博文ID @post: 发布内容 @publish: 是否公开发布 ''' self._mwb.editPost(postid, self._config['usr'], self._config['passwd'], post, publish) def deletePost(self, postid, publish): ''' 删除博文 ''' self._mwb.deletePost(self._config['appkey'], postid, self._config['usr'], self._config['passwd'], post, publish) def getCategories(self): ''' 获取博文分类 ''' return self._mwb.getCategories(self._config['blogid'], self._config['usr'], self._config['passwd']) def getPost(self, postid): ''' 读取博文信息 @postid: 博文ID @return: POST ''' return self._mwb.getPost(postid, self._config['usr'], self._config['passwd']) def newMediaObject(self, file): ''' 资源文件(图片,音频,视频...)上传 @file: { base64 bits string name string type } @return: URL ''' return self._mwb.newMediaObject(self._config['blogid'], self._config['usr'], self._config['passwd'], file) def newCategory(self, categoray): ''' 新建分类 @categoray: { string name string slug (optional) integer parent_id string description (optional) } @return : categorayid ''' return self._server.wp.newCategory(self._config['blogid'], self._config['usr'], self._config['passwd'], categoray) ```
以上是对API的简单封装,万事具有,开始测试web
import core.metablogclient as blogclient client = blogclient.MetablogClient('blog_config.json') client.readConfig() catLst = client.getCategories() print(catLst)
[{'description': '[发布至博客园首页]', 'htmlUrl': '', 'rssUrl': '', 'title': '[发布至博客园首页]', 'categoryid': '0'}, {'description': '[Markdown]', 'htmlUrl': '', 'rssUrl': '', 'title': '[Markdown]', 'categoryid': '-5'}...]
获取了全部的分类信息,其中我在网站上自建了一个随笔分类,也能够获取到json
import core.metablogclient as blogclient client = blogclient.MetablogClient('blog_config.json') client.readConfig() catid = client.newCategory({ "name": "[随笔分类]测试分类", "slug": "", "parent_id": 0, "description": "测试创建一个随笔子分类" }) print("新建分类:", catid)
新建分类: 1536823
可是在博客园网站上没法看到这个分类,使用获取分类再次测试,也没法获取到该分类,使用该分类发布博客,也是无
效的,因此我想__根据年月自动分类__的想法就泡汤啦api
import core.metablogclient as blogclient client = blogclient.MetablogClient('blog_config.json') client.readConfig() posts = client.getRecentPosts(9999) print(posts)
[{'dateCreated': <DateTime '20190829T11:21:00' at 0x2a80990>, 'description': '<p>测试</p>', 'title': '测试', 'enclosure': {'length': 0}, 'link': 'https://www.cnblogs.com/robert-9/p/11428668.html', 'permalink': 'https://www.cnblogs.com/robert-9/p/11428668.html', 'postid': '11428668', 'source': {}, 'userid': '-2'}]
正确拉取现有博文,经过API文档,发现没法获取博文是否处于发布状态,这是一个遗憾服务器
import core.metablogclient as blogclient import datetime client = blogclient.MetablogClient('blog_config.json') client.readConfig() postid = client.newPost({ "time": datetime.datetime.now(), "title": "metaweblog API随笔发布", "description": "##metaweblog API随笔发布\n测试\n", "categories": ["[Markdown]"], "mt_keywords": "metaweblog;python" }, False) print('发布随笔:', postid)
测试发布成功,并能在网站上看到该随笔, 若是想发布为文章,日志或新闻,加入必要的分类便可。markdown
import datetime import base64 import core.metablogclient as blogclient client = blogclient.MetablogClient('blog_config.json') client.readConfig() with open('abc.png', 'rb') as f: bs64_str = base64.b64encode(f.read()) url = client.newMediaObject({ "bits": bs64_str, "name": "abc.png", "type": "image/png" }) print(url)
{'url': 'https://img2018.cnblogs.com/blog/1211514/201908/1211514-20190829114435333-814710358.png'}
测试成功, 这样就能够在上传Markdown 格式以前,自动将本地的图片上传到服务器上了。