前言

交完论文盲审稿,终于从接近一年的实习、秋招和论文的忙碌中闲下来。

在复盘秋招的时候发现自己虽然看过不少书,但缺少整理和思考,所以想趁这个机会梳理一下自己的阅读习惯,希望以后再读新的东西可以更系统高效。但是手动输入图书信息实在太慢了。经过一番调研,我发现有插件Notion Plus可以导出豆瓣图书列表,但似乎缺少维护(我没试),以及我自己想体验一下Notion API,就动了写一个小程序的念头。在这里把搭建过程分享给大家,全当抛砖引玉。

使用场景 : 将单本图书信息从豆瓣导入到Notion database

创建Notion机器人

想要利用Notion提供的API对自己WorkSpace中的block进行操作的话,首先需要创建机器人(integration),并为机器人授予所需要操作的block操作权限。在 我的机器人 页面可以快速创建机器人。

创建新的机器人

填完信息点击创建之后,系统跳转到新的页面。页面最上方给出了这个机器人的Secrets ( 就是 Bearer token),点击Show可以查看和复制。这个token会一直在这个页面,所以不用担心忘记。

Secrets

创建数据表并邀请机器人

Notion 其实是提供了创建Database的API的,但我之前其实已经手动创建过了,所以这里就偷懒没写代码。我的数据表长这个样子:

设计数据表

想偷懒的同学可以直接用我的模板:

做好数据表之后需要邀请机器人,并授权:

邀请机器人

获取豆瓣读书数据

Notion API提供的是基于RESTful架构的接口,虽然官方文档提供的是JavaScript样例,但我自己写Python比较多,所以还是用Python进行开发,还有一个原因就是Python爬取豆瓣数据会更加容易。

def getInfo(url):
header={
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Encoding': 'gzip, deflate, sdch',
'Accept-Language': 'zh-CN,zh;q=0.8',
'Connection': 'keep-alive',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.235'
} r = requests.get(url=url, headers=header)
soup = BeautifulSoup(r.text, 'lxml')
# get info
info = {}
info['title'] = soup.h1.span.text
infos = soup.find(id='info').find_all('span',attrs={'class':'pl'}) for i in infos:
if i.text.strip() == '作者':
info['作者'] = i.next_sibling.next_sibling.text
elif i.text == '出版社:':
info['出版社'] = i.next_sibling.next_sibling.text
else:
info[i.text.strip().strip(':')] = i.next_sibling.text.strip() info['score'] = soup.find(class_='rating_num').text.strip()
info['cover'] = soup.find(class_='nbg')['href'].strip() return info

获取数据的程序非常简单,requests发送请求,BeautifulSoup解析html。这个函数需要的参数url就是豆瓣读书某本书详情页面的链接,如:

数据写入Notion

到这一步其实才开始用Notion API,简单来说就是构造请求,POST到指定的API就可以新建一条记录了。其中,构造请求的关键在于构造各字段(Property)。Notion中各类Property的values可以从property-value-object 中找到详细信息。比如Database的Name字段属于Title property,构造方式如下:

{
"Name": {
"title": [
{
"type": "text",
"text": {
"content": "The title"
}
}
]
}
}

这里有一个小技巧,就是可以先通过程序查询指定页面中各字段的值来获取页面结构,然后直接修改相应的值就可以了。查询指定页面的字段结构,可以构造如下请求:

import requests
token = '***'
database_id = '***'
r = requests.request(
"POST",
"https://api.notion.com/v1/databases/" + database_id + "/query",
headers={"Authorization": "Bearer " + token, "Notion-Version": "2022-02-22"},
)
print(r.text)

其中,token 就是上文创建机器人时Notion自动分配的Secrets ,database_id 就是需要查询的页面的id,页面的id可以直接从链接中找到,下如红框中的一串(从 / 到 ?中间 )就是id。

我截取了查询请求返回值的几个Property:

"页数": {
"id": "U_TO",
"type": "number",
"number": 528
},
"书名": {
"id": "title",
"type": "title",
"title": [
{
"type": "text",
"text": {
"content": "切尔诺贝利的午夜",
"link": null
},
"annotations": {
"bold": false,
"italic": false,
"strikethrough": false,
"underline": false,
"code": false,
"color": "default"
},
"plain_text": "切尔诺贝利的午夜",
"href": null
}
]
},
"封面": {
"id": "jZol",
"type": "files",
"files": [
{
"name": "https://img1.doubanio.com/view/subject/l/public/s33836089.jpg",
"type": "external",
"external": {
"url": "https://img1.doubanio.com/view/subject/l/public/s33836089.jpg"
}
}
]
},

我们可以直接将对应的值替换成我们之前获取到的信息。这里面有很多字段是我们不需要的,比如“id”,或者"annotations" 。Notion会帮我们自动补全。

我构建的完整的Property如下:

body = {
"parent": { "type": "database_id", "database_id": database_id},
"properties": {
"书名": {
"type": "title",
"title": [{"type": "text", "text": {"content": info.get("title",' ')}}]
},
"豆瓣链接": {
"url": url
},
"ISBN": {
"type": "rich_text",
"rich_text": [{"type": "text", "text": {"content": info.get("ISBN",'')}}]
},
"页数": {
"number": int(info.get("页数",0))
},
"出版社": {
"type": "rich_text",
"rich_text": [{"type": "text", "text": {"content": info.get("出版社",' ')}}]
},
"评分": {
"number": float(info["score"])
},
"作者": {
"type": "rich_text",
"rich_text": [{"type": "text", "text": {"content": info.get('作者','')}}]
},
"标签": {
"type": "multi_select",
"multi_select": [{"name": info.get('tag')}]
},
"封面": {
"files": [
{
"type": "external",
"name": info['cover'],
"external": {"url": info['cover']}
}
]
},
"状态": {
"type": "select",
"select": {
"name": info.get('status'),
}
},
},
}

之后将这个Body作为请求的主体发送到相应的Notion API就可以在我们的数据表中添加一条新的记录啦。

re = requests.request(
"POST",
"https://api.notion.com/v1/pages",
json= body,
headers={"Authorization": "Bearer " + token, "Notion-Version": "2022-02-22"}, )

完整代码可以从我的Github获得:Notion_douban

效果

最终的效果如下:

还可以添加一个Gallery View:

Notion-douan:搭建自己的阅读清单的更多相关文章

  1. JDK1.8源码分析03之idea搭建源码阅读环境

    序言:上一节说了阅读源码的顺序,有了一个大体的方向,咱们就知道该如何下手.接下来,就要搭建一个方便阅读源码及debug的环境.有助于跟踪源码的调用情况. 目前新开发的项目, 大多数都是基于JDK1.8 ...

  2. 【Java】用IDEA搭建源码阅读环境

    用IDEA搭建源码阅读环境 参考自CodeSheep的Mac源码环境搭建, https://www.bilibili.com/video/BV1V7411U78L 但是实际上在Windows搭建的差别 ...

  3. 搭建Tomcat6源代码阅读环境

    目标:使用MyEclipse8.5阅读Tomcat6源码. 第一步:在MyEclipse8.5中集成SVN插件. 第二步:从地址http://svn.apache.org/repos/asf/tomc ...

  4. C++程序员的阅读清单

    link:http://www.who1753.com/must-read-c-book-list/ 多读一些优秀的书籍,对于开发者稳固编程基础.提高编程技能有很大帮助.但是,大多时候,初学者不知道应 ...

  5. 用Vue.js搭建一个小说阅读网站

    目录 1.简介 2.如何使用vue.js 3.部署api服务器 4.vue.js路由配置 5.实现页面加载数据 6.测试vue项目 7.在正式环境部署 8.Vue前端代码下载 1.简介 这是一个使用v ...

  6. Python阅读清单

    Python <零基础学Python(第二版)> 包括进阶 The Python Tutorial 绝对权威和主题丰富的官方教程 PEP 8 以及 PEP 257 编码风格/规范 PEP ...

  7. PHP 设计模式阅读清单

    社区文章推荐 S.O.L.I.D 面向对象设计和编程(OOD&OOP)笔记 浅谈 Laravel 设计模式 PHP 完整实战 23 种设计模式 Laravel Dependency Injec ...

  8. 记录下 k8s (1.14.2)使用kubeadm方式搭建和rancher搭建需要的镜像清单

    kubeadm方式 之前一直用的1.12.2版本的,最近想试一下新的版本1.14.2 当然相应的组件镜像版本也需要更新了.镜像版本如下(网络插件使用flannel) k8s.gcr.io/kube-p ...

  9. Spring源码阅读 之 搭建源码阅读环境(IDEA)

    检出源码: GitHub:https://github.com/spring-projects/spring-framework.git 可以按如下步骤:(须确保Git已正确安装) Git正确安装后, ...

随机推荐

  1. linux大工程 - 我要一个属于自己的回收站

    我要开始装13了 'rm -rf 是一个很"粗鲁"的命令,就像windows的shift+delete,删除的文件是无法找回的(当然,除了数据恢复软件,但是很麻烦,很费时)' '为 ...

  2. 如何删除远端已经推送的Commit记录???(Git版本回退)

    如何删除远端已经推送的Commit记录???(Git版本回退) 简单描述 突然事件:刚刚,就在刚刚,发生误了操作. 操作描述:我把修改的文件保存错分支了,已经commit了.并且还push上去了.对, ...

  3. html页面预览pdf文件使用插件pdfh5.js

    html预览pdf文件需要依赖pdf.js 移动端适配需要pdfh5.js 记录移动端适配pdfh5.js的用发 在线预览: https://www.gjtool.cn/pdfh5/pdf.html? ...

  4. dart系列之:集合使用最佳实践

    目录 简介 使用字面量创建集合 不要使用.length来判断集合是否为空 可遍历对象的遍历 List.from和iterable.toList where和whereType 避免使用cast 总结 ...

  5. java的不正确使用方法以及什么情况不能使用java

    一.Python3.6新特性 什么情况下不能运用 Java 泛型   1. 前语 Java 1.5 引入了泛型来保证类型安全,避免在运行时发作类型转换反常,让类型参数化,提高了代码的可读性和重用率.可 ...

  6. jenkins发布代码选择不同分支

    jenkins上传代码分支以前都是用变量的方式,手动实现.过程就像这样 构建时候的界面就像下面这样,需要手动输入分支版本. 或者有固定的上线分支,用参数化构建 选项参数 来选择.总之这些方法比较传统, ...

  7. 攻防世界-Crypto高手进阶区部分Writeup

    1.flag_in_your_hand && flag_in_your_hand1 下载,解压后 打开index文件,直接点击get flag错误,输入其他点击也同样 打开js文件,在 ...

  8. 2021顶级的开源 BI(商业智能)软件和报表工具

    在这个信息化时代,每分每秒都产生海量数据.在海量数据中,挖掘出有用的数据,并且能以较人性化.直观的方式展示这些数据,变得尤为重要.本文将介绍5款顶级开源 BI(商务智能)软件和报表工具,用于商业数据的 ...

  9. Sencha Cmd 常用命令

    1.获取帮助 sencha help generate app 2.创建应用程序 sencha -sdk e:\ext\ext6 generate app -classic SimpleCMS e:\ ...

  10. 千万级 PV是什么意思?

    首先介绍下pv的概念: PV(访问量):即Page View,页面刷新一次算一次. UV(独立访客):即Unique Visitor,00:00-24:00内相同的客户端只被计算一次. IP(独立IP ...