KindleEar是什么?

KindleEar是部署在Google Appengine上的免费应用,主要功能是自动定期通过RSS收集网络文章然后制作成图文并茂的电子书推送至你的Kindle。

主要特性:

优点:

此应用需要自己的服务器吗?

此应用托管在Google App Engine(GAE)服务器上,不需要你自己的服务器。

注意:GAE(Google App Engine)不是GCE(Google Computer Engine),只要应用使用的资源不超其免费额度,则GAE永久免费,但是GCE仅提供60天试用免费。

如何搭建自己的推送服务器?

以下是正规的搭建步骤:

  1. Github 页面上下载KindleEar的最新版本,在页面的右下角有一个按钮"Download ZIP",点击即可下载一个包含全部源码的ZIP文档,然后解压到你喜欢的目录,比如C:\KindleEar(下面以这个为例)。
  2. 首先你需要一个google账号,然后访问 Google Developers Console,新建一个Application。(用来上传KinldeEar用)。
  3. 安装 Python 2.7.x,在此页面中选择你的系统平台对应的2.7.x版本下载,然后直接双击安装。注意不要安装成Python 3.x版本,GAE和KindleEar都暂不支持。
  4. 下载 GAE SDK,这是用来上传GAE程序用的。在此页面中的区段“Google App Engine SDK for Python”中选择你的系统平台对应的版本点击即可下载,然后安装,一路next无话。
  5. 打开资源管理器,进入之前下载的KindleEar目录C:\KindleEar,使用任何文本编辑器打开app.yaml和module-worker.yaml文件,将第一行的kindleear字样修改为你之前申请的GAE程序名(比如kindleear123),保存退出。
  6. 在app.yaml的同一个目录,打开config.py文件,修改SRC_EMAIL为你的gmail账号,DOMAIN为你的应用的域名。其他的选项也可以根据注释有选择性的修改,或者使用默认即可。
  7. 正式上传KindleEar。不能使用Google App Engine Launcher,因为Launcher默认不支持多module应用,这里介绍一下windows下使用命令行的方式。
  8. 依次点击:开始-运行-输入CMD,打开命令行窗口
  9. 进入到App Engine SDK安装目录;例如:
    cd "C:\Program Files\Google\google_appengine"
  10. 输入“上传”命令:
    c:\python27\python.exe appcfg.py update C:\kindleear\app.yaml c:\kindleear\module-worker.yaml
  11. 依次输入gmail账号及密码(密码输入时屏幕不显示)。
  12. 再输入“上传”命令:
    c:\python27\python.exe appcfg.py update C:\kindleear\
  13. 显示上传成功后使用你的浏览器打开域名:kindleear123.appspot.com (举例而已,kindleear123要改为你申请的GAE程序名称),如果能正常打开,则还有最后一步。
  14. 将你的gmail账号加入kindle推送邮箱的白名单。这一步你应该早就会了吧。
  15. 然后呢?享受你自己的推送服务吧!

以下是推荐的简化搭建步骤(使用uploader):

  1. 下载KindleEar和申请GAE账号,并创建一个application。
  2. 下载uploader
  3. 解压uploader到特定目录,将之前下载并解压的KindleEar目录拷贝到此目录下,改名为kindleear,然后双击执行uploader.bat后根据提示输入appid/email/timezone后会正式启动上传程序,输入email和密码即可上传代码。

为什么我收不到推送的RSS?

收不到推送的RSS原因很多,如下是几种可能:

  1. 部署时仅部署了default模块,而没有部署worker模块。比如使用Launcher默认配置上传则导致此情况。
  2. 没有打开"自定义RSS"的投递开关,此开关在设置网页的最下面。
  3. 没有在kindle邮箱的白名单中加入你的gmail地址:
  4. 添加RSS过多导致内存占用过大,程序被自动终止。
  5. 你输入的订阅地址不是合法的RSS/ATOM订阅(XML格式)。
  6. 如果RSS订阅源是Feedburner生成的,你可以在其链接之后添加一个查询字符串'?format=xml',比如:http://xx.com/feed?format=xml.

何为全文RSS?

全文RSS就是在RSS的XML文件中已经给出了文章全文的RSS,使用浏览器打开RSS对应的链接,查看是否已经有全部的文章内容?如果是,则为全文RSS。如果仅给出文章摘要,则不是。

全文RSS能否按照摘要RSS处理?反之是否可以?

全文RSS当然可以按照摘要RSS处理,这样就忽略RSS链接中给出的文章内容,而直接到原链接中获取,只是时间要多花费不少,导致支持的RSS数量下降。如果是摘要RSS,则不能按全文RSS处理,否则会导致文章内容不全。

如何按周订阅?

有些RSS每周更新,这样每天推送同样的内容就蛋疼了点,碰到这种情况,有两种处理方法:

  1. 在books目录下添加一个py文件,将参数deliver_days设置为你需要推送的星期(英文星期单词),注意deliver_days是一个列表,你也可以设置为几个单词,这样的话,其实也可以设置为哪天不推送。
    比如:
    deliver_days=['Friday']
  2. 使用管理员登陆,新增一个账号,退出,使用新账号登陆,添加需要的RSS,然后在“设置”页面仅选择你需要的其中一个“投递日”,在页面下方的“最旧文章”中选择“一个星期”。

如何一天推送多次?

需要及时跟踪网站最新消息的同学可能有一天推送多次的需求,以下步骤告诉你如何实现:

  1. 在books目录下添加一个py文件。
  2. deliver_times设置为你需要推送的整点时间列表。
    比如:
    deliver_times=[6,14,22] #6:00,14:00,22:00三次推送
  3. 如果需要,oldest_article设置为多次推送的间隔秒数,这样就不推送重复文章了。
    比如:
    oldest_article=28800 #8*60*60

URL过滤器功能如何使用?

URL过滤器为高级功能,面向懂python正则表达式的同学,应用场景是这样的:有一些RSS的一部分固定的图像会一直下载不了或者其本身就是烦人的广告图像,为了节省时间支持更多的RSS或更好的阅读体验,则可以过滤这些图像URL,不再下载。URL过滤器支持正则表达式,请严格按python正则表达式的语法编写URL过滤器。

部分RSS有敏感内容,被墙屏蔽了怎么办?

升级到1.5及以上版本,并且将被qiang的RSS的链接协议改为https。

自定义书籍py文件,如何将封面/报头放到py同一目录?

升级到1.5及以上版本,在封面/报头文件设置中有全路径信息即可,如下:
mastheadfile = 'books/xxxx.gif'
coverfile = 'books/xxxx.jpg'

GAE上传遇到SSL出错,如何解决?

墙内的朋友有时候在上传代码时遇到此错误:urllib2.URLError: <urlopen error [Errno 8] _ssl.c:504: EOF occurred in violation of protocol>,如果这样,改hosts即可:“74.125.229.174 appengine.google.com”

有部分文章乱码?

对于自定义RSS和不指定编码的内置书籍,软件使用多种方法综合确定网页的编码:HTTP头/HTML头/python模块chardet检测的编码,最终结果并不是100%正确的,如果检测错误,则文章可能乱码,这在浏览器上偶尔碰到网页乱码一样道理。
因为这种情况很少见,KindleEar仅提供一个不是很优雅的hack方案:手工更改数据库缓存的chardet检测的编码。
方法如下:

  1. 使用admin登陆appid.appspot.com(假定你的应用名字为appid)。
  2. 浏览器地址栏中输入https://appid.appspot.com/dbviewer,翻到页面UrlEncoding区段,查看乱码文章对应网站的编码信息,如果编码不对,记下ID号,进行下一步。
  3. 地址栏中输入https://appid.appspot.com/dbviewer?action=modurlenc&id=dbid&feedenc=fenc&pageenc=penc
  4. 或者你可以在GAE后台的Datastore Viewer中修改。
  5. 至于怎么获取正确的编码,可以通过在浏览器中查看网页源码。
  6. 如果你在dbviewer页面中找不到你需要修改的网站,则说明KindleEar一直没有使用chardet检测过此网站任何网页编码,仅使用HTTP头/HTML头信息,这种情况你可以设置config.py文件中的ALWAYS_CHAR_DETECT变量为True再尝试。
  7. 如果设置ALWAYS_CHAR_DETECT为True还是乱码,则说明chardet检测到的编码错误,并且HTTP头/HTML头编码信息不一致(还是有这种奇葩的网站的),这种情况还可以尝试将TRUST_ENCODING_IN_HEADER_OR_META设置为True。
  8. 尝试了ALWAYS_CHAR_DETECT和TRUST_ENCODING_IN_HEADER_OR_META都不行的话,软件无能为力了,请增加一个py文件,然后手工指定正确的编码吧。

忘记密码了怎么办?

如果是忘记非管理员账号的密码,则可以通知管理员改密码。如果是管理员密码,则可以登陆appengine.google.com,在左边选择"Datastore Admin",删除KeUser的所有数据,则所有账号的信息都会被删除,或者建议将所有数据库都删除,然后重新使用admin/admin登陆你的应用即可。没有找到"Datastore Admin"?则可以先在"Application Settings"里面打开。
如果你会编程,则你会有其他方法,不用我说。

xxx@appid.appspotmail.com邮件地址怎么用?

xxx@appid.appspotmail.com是KindleEar附送的邮件服务,在部署好KindleEar后,你自动拥有了无数个EMAIL邮箱地址,格式为:xxx@appid.appspotmail.com,xxx为任意合法字符串,appid为你的应用名。

推送至亚马逊中国邮箱有比较大的延迟?

这个经过网友们试验,和伟大的墙有关系,有一个解决方法:KindleEar先推送至某个个人邮箱,然后此个人邮箱自动转发至中亚的kindle邮箱。
不过还面临一个问题:部分邮箱设置自动转发需要发到邮箱的验证,而亚马逊邮箱不能登陆无法验证。其实你需要的是找一个不需要目标邮箱确认的邮箱来设置自动转发,比如outlook.com。

为何合并多本书籍推送后无法查词典?

如果有外文RSS而且需要在kindle上查字典的话,请将自定义RSS的语言设置为对应的外文。
同时,还要注意合并书籍推送的其他特性:

  1. 合并后的书籍使用默认报头和封面;
  2. 合并后的书籍使用自定义RSS设定的标题和语言设置;

“高级设置”里的归档和分享功能如何使用?

启用此功能后,KindleEar会在每篇文件的最后都附加一个超链接,在Kindle上点击此超链接会自动打开浏览器将你正在阅读的此文章归档至网络笔记或分享至社交网络(需要打开网络连接)。
有几点需要注意的:

  1. 请先修改config.py里面的DOMAIN为你申请的应用域名;
  2. 如果你在红墙内,可能需要打开“我需要翻墙(针对中国用户)”开关,默认的翻墙转发器采用作者在heroku上搭建的免费服务器: http://kforwarder.herokuapp.com,如果你有余力或者注重隐私,建议自己搭建一个,源码托管在 https://github.com/cdhigh/forwarder。(如果将来墙也封锁了heroku,则此翻墙方法无效)

有的网站需要登陆才能阅读文章的问题如何解决?

有些网站需要先注册账户然后登陆后才能阅读和下载文章,对于此类网站,则可以仿照books目录下的预置书籍,增加一个新的py文件,然后设置这几个属性:

  1. needs_subscription :设置为True
  2. login_url :为此网站的登陆网页URL
  3. form_4_login :可选(如果你不会看网页HTML源码就暂时不用设置),如果不设置或设置为None则KindleEar尝试自动判断;设置为整数则表示此网页中第几个form为登陆表单(0为第一个);设置为字符串则表示对应登陆表单form的名字,'#'打头表示id,'.'打头表示class,否则则匹配name/id/class任何一个。
  4. 登陆KindleEar后,在“我的订阅”页面先订阅对应书籍,然后书籍行右边会新出现一个按钮“登陆信息”, 点击后请在新页面中输入正确的账号和密码。

注1:因为GAE环境的限制,需要执行javascript或要输入验证码的网站则无法支持。

注2:对于一些足够特殊和复杂的网站,可能你需要在书籍子类中重写login()函数。

注3:你输入的密码将加密保存,密钥为每个账号都不一样的8位随机字符串,有一定的安全性,而且我尽量照顾你的密码安全,你可以随时删除保存的密码信息,书籍退订后也马上删除密码,但因为密钥也保存在GAE上(在另外的数据表),所以不能保证很高的安全性,请自己明白并愿意承担其中的风险。

网站在IE6下显示不正常?

在IE6下网站排版混乱并且无法显示导航栏,因为网站的排版采用YAHOO的CSS框架pure,而此框架要求IE7以上的IE,或者chrome/firefox,如果你使用的IE版本过低,建议升级到新版本。

内置书籍订阅时“Separate”选项是什么意思?

一旦你选择了“合并推送”,则所有订阅源都会合并成一本书籍推送至kindle,如果你需要有部分订阅源分开单独推送,则在订阅时选择“Separate“。

部署应用后打开网页出现“internal server error”如何处理?

有部分网友在部署后打开此应用的“我的订阅”和“投递日志”网页会出现“internal server error”错误,一般情况下因为gae没有及时生成对应数据库的索引导致。
你可以打开gae后台,查看logs日志,看是否有“NeedIndexError: no matching index found.”异常,如果有的话,证明是没有生成索引。
你也可以在gae后台查看“Datastore Indexes”,看每个条目的“Status”,正常情况下应该都是“Serving”,如果是“Building”或其他值,则说明索引也没有正确生成。
如果你部署步骤完全正确的话,可以稍等几分钟到几十分钟,等gae自动生成索引,如果gae没有成功自动生成索引,你也可以手动更新索引:
python appcfg.py update_indexes KindleEar/
在终端窗口执行此命令,注意最后一个KindleEar是你保存的此应用的目录名。
如果出现的异常信息中有“UnknownQueueError”,则说明部署有问题,可以先单独执行此命令上传更新队列配置信息:
python appcfg.py update_queues KindleEar/
这几个命令也可以执行一遍试试。(比如手动可以推送无法自动推送则执行 update_cron)
python appcfg.py update_cron KindleEar/
python appcfg.py update_queues KindleEar/
python appcfg.py update_dispatch KindleEar/

如果上面的步骤执行完后还是不行的话,请按照正确步骤重新部署。

如何修改多本书籍合并后的封面?

默认配置下如果合并多本书籍,则合并后的封面会将所有书籍的封面缩小并拼贴在一起,并且每次推送的排列顺序都不一样,此效果由config.py里面的参数项 DEFAULT_COVER_BV 控制,默认为 None。
如果你不喜欢这个效果,设置DEFAULT_COVER_BV为某个文件名则可以取消此效果,比如: DEFAULT_COVER_BV='cv_bound.jpg'

如何订阅微信公众号?

感谢网友 zhu327 的代码贡献,有几个方法可以订阅微信公众号:

  1. 可以在books目录下添加一个py文件,内容和格式可以仿照 Xiaodaonews.py, 里面写上你需要订阅的公众号信息,更多的说明可以打开weixinbase.py查看。
  2. 【推荐此方法】通过作者 zhu327 搭建的 https://diy-devz.rhcloud.com/ 网站爬取公众号文章并转换为RSS,然后在KindleEar中直接订阅此RSS。
  3. 还有另一个网站 WeiRSS 提供微信公众号转RSS服务,可以试用一下,其抓取原理和zhu327的方案基本一致,也是开源方案 Weixin_sogou on github,当前版本比较简单,估计不如zhu327的代码好用。
注意事项:因为微信是非常封闭的体系,腾讯和搜狗可能会时不时修改其接口或防爬取措施,不管哪个网站或解决方案,都无法保证永久有效,如果后续发现内容爬取失效,可能你需要升级了,或者你可以到 https://diy-devz.rhcloud.com/ 确认 zhu327 有没有更新代码。

有关墙的汇总

在天朝的网友在部署时和使用时会遇到一个强大的墙,特别google又是特别重要的黑名单,这是几个简单的说明,其他的请自己解决:

保存到Pocket功能如何使用?

Pocket 是一个比较流行的稍后阅读应用,你在电子书上读到有趣或有用的文章后,可以选择将其发送到你的Pocket账号,然后就可以通过跨平台的Pocket应用来继续阅读。
要启动此功能,请按如下步骤打开:

备注:

投递日志状态wrong SRC_EMAIL的解决方案。

到Gae后台的Settings页面,看看 已经授权的Email列表里面有没有你的发送邮箱地址,如果没有就添加即可。

其他的一些小Tips。

我还有更多问题,到哪里去问?

如果你碰到更多问题,可以到 https://github.com/cdhigh/KindleEar/issues 去提交一个issue,然后等待答复,不过在提交问题之前,还是建议先搜索一下别人先前提交的issues,说不定已经有人重复提过了相关问题呢?
如果没有别人提过类似问题,你在提交新问题的时候,建议附上 GAE后台 的Logs信息,以便定位问题,也可以得到更快的答复。