moear-package-mobi

概览

该项目实现了基于 Scrapy & KindleGenmobi 打包功能,用于将文章列表打包, 供 MoEar 推送使用。

对于 MoEar 来说,并不强求打包插件使用何种技术实现,只要符合 moear-api-common 中定义的相关接口即可。

当前主流的另一种实现为以 KindleEar 为主的,基于 Calibre 移植的打包工具包。 本工具实现时也有考虑使用 Calibre ,但由于其不支持 Python 3.X , 且其实现为直接生成 mobi 文件,故涉及到很多的文件字节操作,在没有任何相关文档可参考的情况下, 实在是晦涩难懂,将其移植到 Python 3.X 下运行难度太高,故转而使用官方提供的转换工具。 庆幸的是,官方转换工具的使用,使得整个实现优雅简洁的多。

安装方法

您可以通过 pip 进行安装,本包仅在 Python 3.X 下测试通过:

pip install moear-package-mobi

项目结构

包路径说明如下:

.
├── __init__.py
├── crawler_script.py       # 用于提供可程序调用Scrapy的爬行类
├── entry.py                # 实现接口定义的入口文件
├── items.py                # Scrapy 的数据模型
├── middlewares.py          # Scrapy 的中间件
├── pipelines.py            # Scrapy 的流水线
├── settings.py             # Scrapy 的参数设置
├── spiders                 # Scrapy 的具体爬虫实现路径
│   ├── __init__.py
│   └── mobi.py             # mobi打包的爬虫主体
└── template                # 模板路径,用来存储用于生成mobi源文件的Jinja模板
    ├── OEBPS
    │   ├── content.opf     # 内容清单模板
    │   ├── toc.html        # html格式的目录模板
    │   └── toc.ncx         # ncx格式的目录模板
    └── post.html           # 文章内容模板

注意

开发时注意需要在 setup.py 中添加如下配置,以便 stevedore 加载该插件:

entry_points={
    'moear.package': [
        'mobi = moear_package_mobi.entry:Mobi',
    ],
},

参考 stevedore 文档,将第三行内容替换为您的具体实现即可

业务流程

书籍生成

主要功能为根据传入的文章列表数据,将其中的图片链接下载到本地,最终打包到 mobi 中。 并将文章内容中相应的图片链接替换为本地相对路径后,通过文章内容模板渲染后保存到本地。 最终,根据模板生成相关清单、目录等文件,拷贝封面、报头等图片后,进行整体 mobi 打包。

此处我是用 Scrapy 主要目的即为,对图片的异步下载,以及缩略图生成等操作。 您完全可以使用其他框架或手写 Request 来实现图片下载工作。

提示

该方法会在 Celery 的单独进程中被调用

注解

传入的文章列表数据,可参考 moear-api-common 中, SpiderBase.format 的实现。 具体用例可参考 moear-spider-zhihudaily 中相关章节的用例说明,里面有很详尽的描述

入口模块

class moear_package_mobi.entry.Mobi(spider, *args, **kwargs)[源代码]

基类:moear_api_common.base.PackageBase

Mobi打包

用以实现基于kindlegen的mobi打包工具

注解

其中的模板实现,参考于 Kindle 期刊杂志格式排版的电子书制作教程

初始化默认配置参数,可在子类中进行覆盖

配置优先级为:用户元数据 > Spider元数据 > 具体Package配置 > Common全局默认配置

参数:
  • spider (dict) – 指定爬虫的信息数据(包括 ‘meta’ 字段的元数据字典, 其中需包含书籍名称用的时间戳)
  • usermeta (dict) – (可选,关键字参数)指定用户的package相关配置元数据, 如:定制书籍名(book_title)等
hook_custom_options()[源代码]

该方法返回当前类的自定义配置项,由基类在 __init__ 方法中调用, 调用点位于,Common默认全局配置完成后,Spider元数据、用户元数据配置前

返回:返回当前类的自定义配置项
返回类型:dict
generate(data, *args, **kwargs)[源代码]

根据传入的数据结构生成最终用于推送的文件字节字符串( bytes() ), MoEar会将其持久化并用于之后的推送任务

参数:data (dict) – 待打包的数据结构
返回:返回生成的书籍打包输出字节
返回类型:bytes

数据模块

class moear_package_mobi.items.MoearPackageMobiItem(*args, **kwargs)[源代码]

基类:scrapy.item.Item

url = None

文章URL

title = None

文章标题

cover_image = None

文章封面图片

content = None

文章正文

url_local = None

文章持久化后的本地路径

toc_thumbnail = None

文章略缩图,文章封面图片持久化后的本地路径

image_urls = None

图片链接

image_urls_removed = None

被filter过滤掉的图片链接

images = None

图片存储返回

管道模块

class moear_package_mobi.pipelines.MoEarImagesPipeline(store_uri, download_func=None, settings=None)[源代码]

基类:scrapy.pipelines.images.ImagesPipeline

实现图片定制化处理操作

item_completed(results, item, info)[源代码]

在正常图片本地化处理管道业务执行完毕后,使用缩略图路径替换原 result[path] 路径, 从而使最终打包时使用缩略图,并根据配置,对缩略图进行灰度处理

参数:item (MoearPackageMobiItem or dict) – 爬取到的数据模型
class moear_package_mobi.pipelines.PagePersistentPipeline[源代码]

基类:object

将爬取到的文章内容本地化到指定路径

process_item(item, spider)[源代码]

将从图片处理管道流过的数据模型中的缩略图链接更新到文章中的相应图片 URL 上, 并对其中的,已删除图片 item['image_urls_removed'] 进行处理, 使其显示内建的删除图标。

最终使用文章模板,对数据模型中的数据进行渲染并输出到指定路径中,完成本地化, 等待最终 mobi 打包

参数:
  • item (MoearPackageMobiItem or dict) – 爬取到的数据模型
  • spider (MobiSpider) – 当前爬虫对象

爬虫模块

代办事项

  1. 实现更多扩展插件功能,如:

    • 文章原始URL二维码插入到文章末尾,便于手机查看&分享
    • 文章首页增加文章字数统计、阅读时间预估等 Dashboard 显示
    • 文章中链接删除,避免阅读中误触发

    注解

    但还需考虑以上功能是是现在打包工具中好,还是独立的扩展插件系统中更优

发布说明

v1.1.2 (2018-06-10 22:44:55)

Bugfix

  1. 增加通用过滤器,优先执行,过滤掉部分链接(当前为过滤掉无 scheme 的 url)

v1.1.1 (2018-05-12 12:23:45)

Bugfix

  1. 修复当文章没有作者时, KindleGen 编译书籍失败的 Bug

v1.1.0 (2018-05-01 22:09:51)

Feature

  1. 增加过滤不支持 tag 的算法逻辑

Bugfix

  1. 修复不支持的 tag 造成 KindleGen 编译警告

Optimize

  1. 当调用 KingleGen 出现错误信息时直接抛出 IOError

v1.0.0 (2018-04-10 22:35:46)

  1. 文章图片缩略图生成
  2. 文章图片灰度处理
  3. 文章 mobi 打包输出