如何用 KindleEar 推送无 RSS 的网站内容(上篇)

之前书伴曾介绍过利用 Calibre 抓取网站内容制成电子书的方法,可以很方便地生成既美观又实用的期刊样式电子书。Calibre 功能的强大毋庸置疑,不过在实际使用时却有一个明显的不便之处:当你想要定时推送某个内容源时,就必须让运行 Calibre 的电脑一直保持开机状态。因此,很多小伙伴选择使用有着类似功能,并且能免费托管在 Google App Engine 服务器上的开源程序 KindleEar 来解决这个问题。

KindleEar 虽然支持直接订阅 RSS,但可惜很多 RSS 供稿可用性并不高,内置的订阅又无法满足个性化的需求,在这种情况下,就有必要学会自己编写可精准获取目标网站内容的订阅脚本。这里所说的“订阅脚本”也可以理解成为 KindleEar 添加内置订阅,内置的订阅其实也是由一个个定制的订阅脚本组成。

写这篇文章的动机是网友 Jone 发给书伴的一封长信,信中详细描述了自己想要解决的问题:如何在没有编程基础的前提下编写 KindleEar 订阅脚本,并能方便地重新部署到 Google App Engine 上。所以书伴花了几天时间研究了下 KindleEar 订阅脚本,并将经验分享给需要的小伙伴。为了顾及没有任何编程经验的小伙伴,本文会尽可能以普通用户的视角撰写,对涉及代码的部分尽可能做到形象化的说明。

目录

[ 上篇 ]
一、KindleEar 的订阅方式
二、KindleEar 的订阅脚本
三、KindleEar 的调试环境
1、安装 App Engine SDK
2、获取 KindleEar 源代码
3、在本地运行 KindleEar
[ 中篇 ]
一、新创建一个订阅脚本
二、订阅脚本的工作原理
三、从网站抽取文章 URL
四、分析 HTML 标签结构
1、分析文章列表的 HTML 标签结构
2、分析文章内容的 HTML 标签结构
五、测试订阅脚本的推送
[ 下篇 ]
一、文章列表的翻页和限定条目
二、文章内容的翻页和细节修改
三、上传到 Google App Engine

由于编写 KindleEar 订阅脚本牵涉到测试环境的配置,导致篇幅较长,所以本文分成了上、中、下三篇。上篇主要是订阅脚本的相关介绍和测试环境的配置步骤,中下篇则是编写订阅脚本的具体步骤。

一、KindleEar 的订阅方式

KindleEar 和 Calibre 一样,支持通过“RSS”或“网页(HTML)”两种方式抓取目标网站上的内容。

KindleEar 对 RSS 和 HTML 有着不同的处理方式。当目标站点提供 RSS 时,它就会用通用的 RSS 处理模块来提取供稿内容生成电子书,也就是前面提到的“自定义 RSS”。直接用 RSS 自然是最方便的,但现实世界的情况总比理想中的复杂,有很多种原因导致我们无法顺利获取 RSS,比如有些网站根本就不提供 RSS,或者提供了 RSS 却只有摘要信息,甚至提供的 RSS 存在格式上的错误无法正常读取等。

RSS 本质上只是一种简单的数据格式,其结构有着相对严格和固定的规范,所以只需要一个通用处理模块就可以应付几乎所有站点的 RSS 供稿。而 HTML 页面就没这么省心了,可以说不同网站的 HTML 标签结构存在着天壤之别,所以当目标站点不提供 RSS 时,就只能为其编写高度定制化的订阅脚本。

说点题外话:可能很多小伙伴会疑惑,为什么很多网站都不提供 RSS 呢?RSS 生来就是为了方便用户追踪网站更新的,从用户角度来看是相当方便——不用访问网站就能获取到网站内容更新,但是这却不可避免地影响到了内容提供者的商业利益。虽然十多年前很多人也为 RSS 做过一些商业化的尝试,但终以失败告终。随着 2013 年 Google 关闭 Google Reader,算是宣告了 RSS 大时代的终结。现在除了一些博客以及尚有情怀的网站外,大都不再提供 RSS 供稿了,即便提供也只是放点摘要信息,最终的目的还是把用户引导到自己的网站上。RSS 并没有消亡,只是因为它给了用户太多自由而不太被商业容忍。

二、KindleEar 的订阅脚本

在《Calibre 使用教程之抓取网站页面制成电子书》这篇文章中,书伴详细介绍了如何通过编写 Recipe 脚本的方式让 Calibre 抓取指定网站的内容,KindleEar 也提供了类似的功能。不过需要注意的是,虽然 KindleEar 的 MOBI 转换模块提取自 Calibre,但是订阅脚本却与 Calibre 的 Recipe 脚本并不通用,这是因为 KindleEar 并没有直接移植 Calibre 的 Recipe 处理模块,而是将其作为参考重新写了一个处理模块,这导致包括脚本后缀名(KindleEar 是 .py,Calibre 是 .recipe)、相关功能的实现等很多方面都有所不同。因此,你必须遵循 KindleEar 提供的相关功能函数为 KindleEar 编写专用的订阅脚本。

KindleEar 内置的抓取脚都存放在其项目目录下的 books 目录中,脚本的文件名均以英文命名并以 .py 为后缀。每个脚本都继承同目录下名为 base.py 的基类,该基类已对很多种订阅方式做了定义,比如 RSS、HTML 页面、漫画等。我们所创建的订阅脚本就是通过继承这个基类,再根据实际情况改写、定制其中的一些参数和函数,从而实现对目标网站内容的精准抓取。KindleEar 的作者在 base.py 做了大量注释,如果你有一定的编程经验,完全可以根据这些注释说明来理解其中的参数和函数都是如何工作的。

三、KindleEar 的调试环境

由于 KindleEar 的运行依赖于 Google App Engine 环境,无法像用 Calibre 测试 Recipe 脚本那样直接在本地运行,所以为了方便测试编写的 KindleEar 订阅脚本,我们需要在本地搭建可以为 KindleEar 虚拟运行环境的 Google App Engine SDK(Windows 还需要安装 Python 环境和相关的 Python 库)。

不要害怕任何技术性字眼,按照步骤一步步做一般不会有问题。注意不要忽略任何一段文字。

1、安装 App Engine SDK

下面是 Google App Engine SDK 的下载链接,请根据自己的系统类型选择下载安装:

因为 KindleEar 是 Python 程序,所以 SDK 还会依赖 Python 环境。macOS 系统和 Linux 系统都预装了 Python,而对于 Windows 系统,如果没有安装 Python,就需要手动安装 2.7.x 版本的 Python:

* 提示:macOS 系统虽然内置了 Python 环境,但是并不推荐直接使用它,而是推荐使用 Homebrew 安装独立的 Python 环境。Homebrew 是一款包管理器,支持 macOS(或 Linux)系统,它能安装和管理独立于原生系统环境的工具包,可有效避免对原生系统环境产生影响,对于没有包管理器的 macOS 系统(或 Linux 系统中的非 root 用户)来说非常方便。

此外,KindleEar 的运行还依赖一些第三方 Python 库,这些库需要在命令行中用 pip 命令安装。

注意,本文之后的内容经常会用到命令行,所以应记住,当文中说到输入命令时,你需要打开“终端”(Windows 系统则打开“命令提示符”),把相关命令输入(或拷贝)进去,按回车执行。

macOSLinux 用户可直接通过执行下面的命令安装这些第三方 Python 库:

pip install lxml pillow jinja2 pycrypto

* 提示:在 macOS 或 Linux 系统中,如果用的是原生系统的 Python 环境,并且是非 root 用户,则需要附加 sudo 命令。

Windows 用户需要先下载安装微软的 Microsoft Visual C++ Compiler for Python 2.7,因为安装第三方 Python 库的对其有依赖。安装完成后,通过以下命令安装 KindleEar 依赖的第三方 Python 库:

C:\Python\Scripts\pip install lxml pillow jinja2 pycrypto

* 提示:上面这条命令假设你的 Python 是默认安装在 C 盘的,如果指定了其它磁盘,请自行更改路径。

2、获取 KindleEar 源代码

首先需要获取一份 KindleEar 源代码到本地。你可以通过下面的链接下载 ZIP 包解压缩备用:

如果你的电脑已经安装了 Git 工具,也可以通过 Git 的 Clone 命令将源代码拉取到本地:

git clone https://github.com/cdhigh/KindleEar.git

为了之后上传方便,建议去 GitHub 注册一个账户,然后把 KindleEar 项目 Fork 一份到自己的账户下,这样,在添加好编写的订阅脚本后,可以先将源代码 Push 到你 Fork 的项目中,再按照 KindleEar 搭建教程中的“自动上传”方式利用 Google App Engine 的云端 Shell 重新部署你 Fork 的 KindleEar 项目。

3、在本地运行 KindleEar

接下来就是让 KindleEar 在本机运行起来了。注意,在这里我们不使用带界面的 Google App Engine Launcher,而只使用它附带的命令行工具。默认情况下,Windows 系统可以直接在命令提示符中使用这些命令,而 macOS 系统需要先打开界面版的 Google App Engine Launcher,点击软件的菜单中的“Make Symlinks…”创建命令软链接才能使用命令。Linux 系统需要添加 PATH 变量才能使用命令。

打开终端(Windows 系统打开命令提示符)并定位到 KindleEar 的项目目录。假设项目在系统桌面上。

macOS 系统需要输入类似以下命令定位到 KindleEar 项目目录(注意替换 YOURNAME):

cd /Users/YOURNAME/Desktop/KindleEar

Windows 系统则需要输入类似以下命令定位到 KindleEar 项目目录(注意替换 YOURNAME):

cd C:\Users\YOURNAME\Desktop\KindleEar

定位到 KindleEar 项目目录后,输入以下命令让 KindleEar 运行起来(注意有两个空格):

dev_appserver.py ./app.yaml ./module-worker.yaml

在 Windows 系统下,有小伙伴反馈了两个问题。一个是输入 dev_appserver.py 无法成功执行命令,而是被记事本打开了,这是因为你强制设定了 .py 文件的打开方式,需要将其打开方式恢复成 python:随便找一个 .py 为后缀的文件,通过右键属性更改该文件的默认打开方式为你所安装的 python.exe。

另一个是在 Windows 7 系统下,输入 dev_appserver.py 提示 error: too few arguments 错误,这是由于某种原因 Python 无法读取命令后的参数导致的,这需要通过修改注册表来修复。在命令提示符中输入 regedit 打开注册表,依次展开 HKEY_CLASSES_ROOT\Applications\python.exe\shell\open\command,如果发现 command 的值不是 "C:\Python27\python.exe" "%1" %* 就改成这个(通常是缺少了 %*)。

当你看到终端(或命令提示符)上出现如下所示的输出,就说明 KindleEar 已经在本机正常运行了:

INFO     2019-05-11 13:51:41,358 sdk_update_checker.py:231] Checking for updates to the SDK.
INFO     2019-05-11 13:51:44,383 sdk_update_checker.py:247] Update check failed: 
INFO     2019-05-11 13:51:44,613 api_server.py:275] Starting API server at: http://localhost:49342
INFO     2019-05-11 13:51:44,625 dispatcher.py:256] Starting module "default" running at: http://localhost:8080
INFO     2019-05-11 13:51:44,667 dispatcher.py:256] Starting module "worker" running at: http://localhost:8081
INFO     2019-05-11 13:51:44,672 admin_server.py:150] Starting admin server at: http://localhost:8000
INFO     2019-05-11 13:51:46,928 instance.py:294] Instance PID: 37115

打开浏览器(推荐用 Chrome),输入 http://localhost:8080 即可访问运行在本机上的 KindleEar 程序,输入默认的用户名和密码 admin 即可登入控制界面。至此,KindleEar 的调试环境便准备好了。

本文的下篇将会以 China Daily 为例,由浅入深详细说明如何编写 KindleEar 的订阅脚本。编写好的脚本可抓取指定板块下指定数量和日期的新闻条目,并将其整合到同一本电子书中,其中还包括对内容页、分页等细节的处理。最后,把测试成功的订阅脚本上传部署到 Google App Engine 的生产环境上。

▲ China Daily 网站抓取效果

为方便编写代码,建议先备好一款代码编辑器,推荐 Sublime TextVisual Studio Code。如果你对 KindleEar 订阅脚本有什么疑问,或者发现本教程存在的谬误或不详尽之处,欢迎留言。

你可继续阅读:《如何用 KindleEar 推送无 RSS 的网站内容(中篇)

有帮助,[ 捐助本站 ] 或分享给小伙伴:

发表评论

标注为 * 的是必填项。您填写的邮箱地址将会被保密。如果是在本站首次留言,审核后才能显示。
若提问,请务必描述清楚该问题的前因后果,提供尽可能多的对分析该问题有帮助的线索。

小伙伴们发表了 40 条评论

  1. 您好,现在运行不了KindleEar,百度也找不到解决办法,请问一下该怎么办?
    c:\KindleEar>dev_appserver.py ./app.yaml ./module-worker.yaml
    INFO 2019-09-18 19:18:59,980 sdk_update_checker.py:231] Checking for updates to the SDK.
    INFO 2019-09-18 19:19:06,515 sdk_update_checker.py:247] Update check failed:
    WARNING 2019-09-18 19:19:06,516 devappserver2.py:291] The default encoding of your local Python interpreter is set to ‘gbk’ while App Engine’s production environment uses ‘ascii’; as a result your code may behave differently when deployed.
    Traceback (most recent call last):
    File “C:\Program Files (x86)\Google\google_appengine\dev_appserver.py”, line 96, in
    _run_file(__file__, globals())
    File “C:\Program Files (x86)\Google\google_appengine\dev_appserver.py”, line 90, in _run_file
    execfile(_PATHS.script_file(script_name), globals_)
    File “C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\devappserver2\devappserver2.py”, line 600, in
    main()
    File “C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\devappserver2\devappserver2.py”, line 588, in main
    dev_server.start(options)
    File “C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\devappserver2\devappserver2.py”, line 355, in start
    configuration.modules[0].application_root)
    File “C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\devappserver2\api_server.py”, line 654, in create_api_server
    if options.support_datastore_emulator else None)
    File “C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\devappserver2\stub_util.py”, line 201, in setup_stubs
    consistency_policy=datastore_consistency))
    File “C:\Program Files (x86)\Google\google_appengine\google\appengine\datastore\datastore_sqlite_stub.py”, line 618, in __init__
    factory=sql_conn)
    sqlite3.OperationalError: unable to open database file

    • 错误提示找不到 sqlite 数据库,可能因为某种原因(比如用什么软件清理过系统垃圾)删除了之前生成的数据库,导致运行环境找不到它。你可以尝试在运行 dev_appserver.py 命令的时候加上一个参数 --clear_datastore 让本地运行环境重建包括数据库在内的所有数据。

  2. 你好,非常感谢分享。
    但是我到最后一步的时候卡住了。
    dev_appserver.py ./app.yaml ./module-worker.yaml
    输入后显示的是
    ‘dev_appserver.py’ 不是内部或外部命令,也不是可运行的程序
    或批处理文件。
    因为我没有什么编程基础,这个问题怎么处理呢?我看了一下下载目录里面确实找不到’dev_appserver.py’ 。
    谢谢!

    • 首先你需要确认,已经安装了 APP Engine SDK。然后还需要确认,已经按照本文第三部分的第 3 个步骤的说明,根据不同类型的系统,把 SDK 的可执行程序所在目录添加进了环境变量。

  3. 192:KindleEar #### $ dev_appserver.py ./app.yaml ./module-worker.yaml
    INFO 2019-06-25 11:31:48,475 sdk_update_checker.py:231] Checking for updates to the SDK.
    INFO 2019-06-25 11:31:54,507 sdk_update_checker.py:247] Update check failed:
    INFO 2019-06-25 11:31:54,605 api_server.py:275] Starting API server at: http://localhost:50852
    INFO 2019-06-25 11:31:54,614 dispatcher.py:256] Starting module “default” running at: http://localhost:8080
    INFO 2019-06-25 11:31:54,673 dispatcher.py:256] Starting module “worker” running at: http://localhost:8081
    INFO 2019-06-25 11:31:54,681 admin_server.py:150] Starting admin server at: http://localhost:8000
    INFO 2019-06-25 11:31:56,857 instance.py:294] Instance PID: 76635

    我发现我的除了跟你的PID数字显示不同,其他的都一样,
    但是我的http://localhost:8000页面打开,跟你的不一样,
    这是我的截屏,我的电脑是Mac,
    ![截屏](https://i.loli.net/2019/06/25/5d1206fea338971610.png)

    • 截图界面是 worker 模块,但是你给出的日志 default 模块的端口确实是 8000。你可以点击截图页面中的 default 连接看看它到底是用的哪个端口。

    • 出现这个WARNING 2019-05-30 09:15:24,132 simple_search_stub.py:1196] Could not read search indexes from c:\users\lzlyv\appdata\local\temp\appengine.kindleear\search_indexes

  4. 您好,有一个问题想问一下:
    在执行代码:dev_appserver.py ./app.yaml ./module-worker.yaml
    显示:
    WARNING:Your python27 micro version is below 2.7.12, our current production version.
    电脑系统是MacOS10.14.4,这个命令执行的时候应该是电脑自带的默认python2版本,
    我应该怎么做,才能够没有这个警告⚠️,或者说,这个warning无伤大雅,可以直接忽略。

    • 还有一个问题,我按照操作一步一步来,
      输入代码:dev_appserver.py ./app.yaml ./module-worker.yaml
      之后进入网址:http://localhost:8080/
      居然显示:该网页无法正常运作localhost ,目前无法处理此请求,HTTP ERROR 500。
      去查了一下:500 Internal Server Error 是表示服务器端错误的响应状态码,意味着所请求的服务器遇到意外的情况并阻止其执行请求。
      有甚多不明白之处,还望包含。

      • 只通过 HTTP 的 500 错误无法排查问题出在哪里,你需要看终端上给出的具体错误提示(一般是 Python 的 Traceback 错误提示)。

    • 这个提示说明的是 SDK 要求最低 Python 版本为 2.7.12,而系统自带 Python 版本有点低。如果一切运行正常可以忽略这个提示,不过对于 macOS 系统还是建议按照文中的提示,安装一个 Homebrew,安装独立的 Python 环境。

  5. 上传完打开 http://APPID.appspot.com 显示
    Error: Server Error
    The server encountered an error and could not complete your request.
    Please try again in 30 seconds.
    错误报告显示
    UnicodeDecodeError: ‘ascii’ codec can’t decode byte 0xc3 in position 5:
    请问如何解决啊?

      • 我是根据这里操作的【为了之后上传方便,建议去 GitHub 注册一个账户,然后把 KindleEar 项目 Fork 一份到自己的账户下,这样,在添加好编写的订阅脚本后,可以先将源代码 Push 到你 Fork 的项目中,再按照 KindleEar 搭建教程中的“自动上传”方式利用 Google App Engine 的云端 Shell 重新部署你 Fork 的 KindleEar 项目。】
        我加了一个自定义书籍,里面有í符号。
        后来我上传源码
        [rm -f uploader.sh* && \
        wget https://raw.githubusercontent.com/kindlefere/KindleEar-Uploader/master/uploader.sh && \
        chmod +x uploader.sh && \
        ./uploader.sh],也出现这样的错误。

            • 我直接把你 Github 下的 KindleEar 项目上传到 GAE,可以正常访问,并没有出现你留言中说的编码错误。在订阅列表中也能看到《El País》。也就是说 ELPAIS.py 这个脚本没有编码问题。

              对于自己修改的项目,建议还是用命令上传,不要用那个 Shell 脚本。上传命令也很简单,在云端 Shell 中把你 KindleEar 上的项目 Clone 下来(如果已 Clone 就用 Pull 命令更新),然后用 cd 命令定位到 KindleEar 项目目录用 appcfg.py 命令上传即可:

              git clone https://github.com/kimfyy/KindleEar.git
              cd KindleEar
              appcfg.py update app.yaml module-worker.yaml

              如果上传后还是出现错误,建议去 GAE 的日志中看一下错误的原因是什么。

              另外,我看 ELPAIS.py 这个脚本中的 URL 都是 RSS 地址,为什么不直接用 KindleEar 的“自定义 RSS”功能呢?

              • 【我直接把你 Github 下的 KindleEar 项目上传到 GAE,可以正常访问】请问要怎么上传?我根据原有书籍再次修改了ELPAIS.py文件,但更新之后已部署的文件并没有变化,ELPAIS.py还是原来错误的格式。可能是我的上传的方式不对,没有更新成功。我输入./uploader.sh,显示

                [已存在 KindleEar 源码,是否更新?[y/N]y
                Updating 293e820..659258d
                error: Your local changes to the following files would be overwritten by merge:
                        books/ELPAIS.py
                Please commit your changes or stash them before you merge.
                Aborting]没有更新

                【在云端 Shell 中用 cd 命令定位到 KindleEar 项目目录】这个 KindleEar 项目目录该在哪里找?请问该怎么操作啊?

                是这个错误报告吗?我看不懂……😂

                [Traceback (most recent call last):
                  File "/base/alloc/tmpfs/dynamic_runtimes/python27g/43d5822312de17fd/python27/python27_lib/versions/1/google/appengine/runtime/wsgi.py", line 240, in Handle
                    handler = _config_handle.add_wsgi_middleware(self._LoadHandler())
                  File "/base/alloc/tmpfs/dynamic_runtimes/python27g/43d5822312de17fd/python27/python27_lib/versions/1/google/appengine/runtime/wsgi.py", line 311, in _LoadHandler
                    handler, path, err = LoadObject(self._handler)
                  File "/base/alloc/tmpfs/dynamic_runtimes/python27g/43d5822312de17fd/python27/python27_lib/versions/1/google/appengine/runtime/wsgi.py", line 96, in LoadObject
                    __import__(cumulative_path)
                  File "/base/data/home/apps/s~chachareads/1.418224781598922311/apps/module_front.py", line 59, in 
                    b = Book.all().filter("title = ", book.title).get()
                  File "/base/alloc/tmpfs/dynamic_runtimes/python27g/43d5822312de17fd/python27/python27_lib/versions/1/google/appengine/ext/db/__init__.py", line 2116, in get
                    results = self.run(limit=1, **kwargs)
                  File "/base/alloc/tmpfs/dynamic_runtimes/python27g/43d5822312de17fd/python27/python27_lib/versions/1/google/appengine/ext/db/__init__.py", line 2080, in run
                    iterator = raw_query.Run(**kwargs)
                  File "/base/alloc/tmpfs/dynamic_runtimes/python27g/43d5822312de17fd/python27/python27_lib/versions/1/google/appengine/api/datastore.py", line 1698, in Run
                    itr = Iterator(self.GetBatcher(config=config))
                  File "/base/alloc/tmpfs/dynamic_runtimes/python27g/43d5822312de17fd/python27/python27_lib/versions/1/google/appengine/api/datastore.py", line 1677, in GetBatcher
                    return self.GetQuery().run(_GetConnection(), query_options)
                  File "/base/alloc/tmpfs/dynamic_runtimes/python27g/43d5822312de17fd/python27/python27_lib/versions/1/google/appengine/api/datastore.py", line 1549, in GetQuery
                    filter_predicate=self.GetFilterPredicate(),
                  File "/base/alloc/tmpfs/dynamic_runtimes/python27g/43d5822312de17fd/python27/python27_lib/versions/1/google/appengine/api/datastore.py", line 1594, in GetFilterPredicate
                    property_filters.append(datastore_query.make_filter(name, op, values))
                  File "/base/alloc/tmpfs/dynamic_runtimes/python27g/43d5822312de17fd/python27/python27_lib/versions/1/google/appengine/datastore/datastore_query.py", line 114, in make_filter
                    properties = datastore_types.ToPropertyPb(name, values)
                  File "/base/alloc/tmpfs/dynamic_runtimes/python27g/43d5822312de17fd/python27/python27_lib/versions/1/google/appengine/api/datastore_types.py", line 1800, in ToPropertyPb
                    pbvalue = pack_prop(name, v, pb.mutable_value())
                  File "/base/alloc/tmpfs/dynamic_runtimes/python27g/43d5822312de17fd/python27/python27_lib/versions/1/google/appengine/api/datastore_types.py", line 1599, in PackString
                    pbvalue.set_stringvalue(six_subset.text_type(value).encode('utf-8'))
                UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 5: ordinal not in range(128)]

                我想把这个西语报纸的rss集中在一个文件里,这样方便查词典以及整理标注,在自定义订阅里可以订阅零散的英语rss。

                • 没变化就表示上传没成功。上传 KindleEar 简单说就两步,先获取到源码,再用 appcfg.py 命令上传到 GAE。

                  不过你得清楚你上传的思路是什么。是想要在本地直接把源码上传到 GAE(具体步骤参考《KindleEar 搭建教程》的手动上传部分),还是想要从云端 Shell 要把 Push 到 GitHub 的代码 Pull 下来上传到 GAE。因为本地上传步骤比较繁琐,所以才推荐利用云端 Shell 从 Github 拉取源代码上传。

                  KindleEar 的设置中有“多本书籍合并投递为一本”这个选项的,勾选并保存之后,所有自定义 RSS 都会合并成一本书推送。

  6. 您好,3.1节安装安装 App Engine SDK时,您只是提到下载安装 App Engine SDK包完成安装,但是我下载以后并没有发现有exe或者是bat文件,请问要怎么安装?

          • 您好,我把所有项目完成以后,运行命令也出现了”info……PID”等一连串代码,但是在浏览器始终打不开http://localhost:8080 地址,提示为“localhost 拒绝了我们的连接请求”,具体截图已经发您邮箱,请您帮助,谢谢

            • 你提供的截图显示,comic 中的 yuna.py 想要从 tencentbase.py 中导入 TencentBaseBook 这个类,却找不到 tencentbase 这个模块。但是我看了一下代码,KindleEar 自带的 yuna.py 并没有导入 TencentBaseBook 这个类。

              你对代码做改动了吗?如果改动了代码最好说一下都改了什么。

              • 谢谢您!已经搞定。
                我fork源码以后把book文件夹中不需要的订阅脚本删除了,可能是误删导致了上面的问题。我直接用您提供的源码以后,目前已经成功登陆

                • 删除不需要的订阅脚本需要注意清理相关的一些模块依赖。比如想要删除 comic 下 cartoonmadbase.py 模块,就要在 __init__.py 文件中移除对该模块的导入,同时还要把所有依赖此模块的其它 py 模块也删除。

      • 不知道有什么办法能实现自动抓取并推送存在网站上的*_001.mobi, *_002.mobi顺序文件?

        • 如果下载链接有规律,可以直接用下载软件的批量下载功能实现。比如迅雷就支持批量任务,假设想要下载网站 http://example.com 上的 _001.mobi 到 _100.mobi 这 100 个文件,可以在新建的批量任务中设定含通配符的 URL:http://exsample.com/_(*).mobi,然后将把通配符匹配长度设为 3,就可以批量下载这些文件了。

  7. 什么年代了,还装py2,不知道py2马上就要停止支持了嘛?而且py2编码暗坑无数,我不信你没被编码搞到脑袋爆炸过。

    • 选择 Python2 主要是因为 KindleEar 依赖的 Calibre 处理模块不支持 Python3。这个问题在 KindleEar 的 Issue 中有讨论:考虑兼容python3?

      不过 Calibre 在 3.41.3 版本的更新日志中表示,正在对代码库做了大量更改,以便为支持 Python3 做好准备。如果到时候 KindleEar 替换成支持 Python3 的 Calibre 模块,就可以用 Python3 环境了。或者你自己更改目前的 Calibre 模块源代码使其支持 Python3 也可以。