使用calibre抓取2013年的MSDN Magazine

前段时间入手Kindle Paperwhite,这已经是我第三个Kindle设备了。想当年我花了四五千块钱,在亚马逊美国站上跟着老美预定,可谓是全世界第一批Kindle DX(大屏幕的那款阅读器)用户,不过用着用着后来还是去玩平板了。这次Kindle Paperwhite出了国行设备,才849元,顿觉实在是太便宜了,立即下单,第二天就拿到了这台设备。

有了设备自然要用,除了官方书店里买的书以外,第三方的内容自然也必不可少,毕竟目前国内的Kindle电子书还太少(尤其是计算机方面的),还好之前也从国外买了不少mobi电子书,可以直接看。更重要的是,我发现可以使用calibre这个电子书管理神器来抓取网络上的内容,生成一本电子期刊,甚至可以利用亚马逊提供的邮箱推送服务来传送到Kindle设备上。

calibre可以通过一个RSS链接经过简单设置转化为电子书,是为“基本模式”,与此相对的“高级模式”便是自己编写Python脚本来抓取内容了,这样的抓取脚本被称为“recipe”。calibre为此提供了一个抓取框架,让我们覆盖一些方法,提供一些基本信息,就会去自动下载网页内容了。其实calibre也已经内置许多新闻源的抓取脚本了,但自带的MSDN Magazine脚本只能通过RSS来获取最新的内容,而我的目标是将某个月的内容抓取成一本书,要实现这一点只能自己动手丰衣足食了。

本来我还想看看是否能够使用一个脚本来抓取历史上所有的内容,结果发现这个基本很难。我猜MSDN Magazine的编辑们也是一群不懂技术的人,甚至是交给第三方公司在维护,用了一款很土鳖的CMS系统,生成的HTML格式很差。还好,每一年的版式似乎还是相同的,那我至少可以用同一份脚本来抓取2013年里每个月的内容。尽管如此,要获取所有文章的栏目,标题以及简介还是一份挺麻烦的工作,因为HTML使用地不规则好么!

至于calibre抓取框架本身,要说复杂倒也还好,只不过文档实在讲的有些不清不楚,又难以调试,所以开发起来只得不断尝试,效率很低。这个框架用到了Beautiful Soup,但我根据它的文档却发现好多地方不太一样,后来才发现calibre集成的是其旧版。更坑爹的是,根据Beautiful Soup文档中的包引入方式:

from BeautifulSoup import BeautifulSoup, NavigableString

这么做不会出错,也能正确调用其API,但却无法与框架中的soup对象配合使用,例如使用isinstance来判断其中的文本节点是否是NavigableString类型的对象,居然会返回False!后来才发现,原来在calibre中需要这么做才行:

from calibre.ebooks.BeautifulSoup import BeautifulSoup, NavigableString

发现了没?框架中使用的是calibre.ebooks.BeautifulSoup包,而不是BeautifulSoup。既然如此,那为什么还要让它引入成功?为什么我将一个BeautifulSoup节点添加到框架的DOM树中时,既没有报错也不生效?总之,这些坑浪费了我许多时间,真是岂有此理。

2013年MSDN Magazine的抓取脚本我已经上传到了GitHub上,欢迎随意使用。最近我还打算写几个脚本用来抓取其他一些内容,例如每日的InfoQ新闻等等。InfoQ的RSS只输出摘要,令人不爽,但这对于calibre来说完全不成问题——反正内容是去网页上抓下来的。

文章来源:

Author:jeffz@live.com (老赵)
link:http://blog.zhaojie.me/2013/06/calibre-recipe-for-msdn-magazine-2013.html