2

DouBanReader是一个自动根据你的豆瓣读书标记生成读书报告的脚本。适用对象是像我这种豆瓣读书的重度用户,会在豆瓣上标记自己读过的每一本书,并且会很负责地打分与写review。对于这样的用户,这个项目可以帮你一键生成读书报告,并且格式化成MarkDown格式,之后你再发布到各大博客平台或者自己转成其他格式(HTML,PDF和图片等)都非常容易。

动机

我自己自己是一个重度豆瓣读书用户(注意这里要区分豆瓣读书和豆瓣阅读的区别)。最近两年的年阅读量都在45到50本之间,今年上半年更是因为工作任务比较少的关系,有几个月的月阅读量都在5本以上。同时,我也信奉光读书不动笔相当于没读的道理,所以从去年开始,我就开始写每个月的阅读报告。那么这就带来一个问题——一篇阅读报告中,很多工作其实都是重复的:

  1. 对于每一个本书的review其实我已经在豆瓣读书上都写过了(一般刚一读完我就会着手写心得然后发在豆瓣读书上)
  2. 组织阅读报告格式时,要去豆瓣搜集书的信息:封面的图片和豆瓣链接

这些工作做起来又无聊又容易出错(复制黏贴很容易黏错或者黏漏了),所以我就萌生了做一个自动生成阅读报告的工具。

功能点

做一个项目之前肯定要先确认需要做哪些功能点,所以这里先列一下这个项目的功能点以及完成情况。

豆瓣授权

由于要读用户的豆瓣数据,那么就要接入豆瓣的API,那么就要先向豆瓣API申请授权。具体的授权流程可以参见:使用OAuth2.0访问豆瓣API,具体的豆瓣API说明可以参见:豆瓣开发者服务

获取用户的读书信息

核心功能点。要获取的数据分三块:图书链接、图书封面和用户书评(review)。同时这些数据的获取要能按照时间区间区分(用数字代表月份,0代表全年)。

主要调用API参见:图书Api V2。具体的流程分成两步:

  1. 获取用户在特定时间段内的『已读』数据信息集合(这一步就可以获取到图书链接和封面图片了)
  2. 获取用户对每本书的书评(review)

其中,第一步很好做,因为API直接提供了这些数据,第二点就是坑多且深,因为API并不直接提供,这也是非常值得吐槽的点:豆瓣的开放API有两版,但是V2现在就像是还没做完就放弃了一样,根本没有完全覆盖到V1,再具体到用户书评这一点上,V1虽然相较V2是提供了相关的接口,但是普通权限只能读一个人的所有书评并且还不是全文,高级权限也没有提供具体到特定用户对特定图书的书评的数据接口。

因此,对于第二步,还得将其拆分成三个小步骤:获取已读图书ID-->获取相应图书所有书评-->筛选出当前用户书评并直接获取相应页面信息-->对书评页面的HTML代码进行正则匹配找出书评内容。本来在我看来是应该由API提供的数据,因为豆瓣开放平台没有提供,所以只能绕这么大一圈,而且还留下了很多隐患:遍历所有书评需要多次网络请求,增加了不可靠性;用正则匹配来处理HTML页面的时效性问题……

生成MarkDown文件

根据模板,将获取到的数据填充进去,生成一篇MarkDown格式的文章。具体的格式可以可以参见:四月份阅读报告

生成图片(未完成)

设定这个功能的初衷本来是想方便发微博和微信,而且以为这个功能应该是有库可以支持和提供的。但是等到准备开始做的时候,调查一圈之后发现:库只有图片绘制库,想要完成这个功能需要自己写很多代码,而且如果想要生成的图片格式好看,需要的工作量不亚于再开一个小工程。有鉴于此,就将这个功能点先延后了,以后如果有时间的再进行补充。

豆瓣API的那些坑

这个是我在做这个项目时,遇到的豆瓣开发平台的坑,坑是指在API文档中没有指明的或者很容易让人误解的地方,这些地方你遇到错误的时候完全不知道你自己错在哪里,等在网上查到原因的时候,第一反应就是:『卧槽,这文档上根本就没写嘛,这我怎么能知道?!』,或者『卧槽,这里怎么能这样设计,算几个意思呀,真特么麻烦呀!』。把这些坑写出来也是为了能给以后的开发人员节省点时间(虽然我现在都觉得以豆瓣API V2的这个质量,还有没有开发人员原因为其开发应用了)。

  1. 在获取access_token时(https://www.douban.com/service/auth2/token)需要在headers中加入'Content-Type': 'application/x-www-form-urlencoded',不然会一直报400错误,提示"required_parameter_is_missing: client_id"。
  2. 在获取当前用户信息时(https://api.douban.com/v2/user/~me)需要在headers中加入'Authorization': 'Bearer ' + access_token,不然会一直报403错误。
  3. 获取用户书籍收藏信息时,所给出的时间区间参数需要带『时区』不然会被直接无视。正确的GET请求URL应为:api.douban.com/v2/book/user/findingsea_ly/collections?status=read&from=2015-06-01T13:14:15+08:00&to=2015-07-01T13:14:15+08:00。
  4. 豆瓣的API对于评论的读取限制非常多,没有办法用用户ID和图书ID就直接获取到特定用户对于特定图书的评论(reivew),同时如果获取特定图书的所有评论信息进行遍历,其中也只能得到用户评论的summary(非全文,三个省略号结尾),暂时想到的办法也只能通过对所有信息的遍历,得到特定的那一条后再根据其中的评论链接,用爬虫进行爬取。

项目依赖

由于生成图片的功能点没有完成,所以本次只额外用到了一个网络请求包:Requests: HTTP for Humans

项目总结

总体而言,DouBanReader是一个解决了我的实际需求的小项目,就功能点上来说,并没有难的地方,但同样能学到很多小细节,比如字符串写入文件前的格式化(Python2中文操作不可避免的)和正则表达式的使用技巧(去除各种空白、URL解析和HTML正则查找等)。所以我对这个项目的完成度和学习度就还是挺满意的,再接再厉吧。

GitHub - findingsea/DouBanReader

以上。


findingea
1.1k 声望64 粉丝