用python创建epub文件的一些知识点

概述

Alt

读取json配置文件,然后把几个xhtml文件合并为epub的python库。配置文件里包含了书名、作者、封面图像路径、各个章节的路径和章节名称。本文用到的库:

from ebooklib import epub

内容包括:

  • 书脊 spine
  • 封面 set_cover

要点

书脊的概念 spine

书脊这个词用的真的好,确实和实体书脊是一样的。但是应该把书横放在桌子上,书脊对着自己,这样观察就特别容易理解。如果把书立起来,顺序就会变成从右往左,这样很不舒服。一本书,从上往下(和写代码的顺序一样,看起来像一个列表)依次是:

  • 封面
  • 简介
  • 目录页(你把它当成一个名字为“目录页”的章节即可,以免和后面的目录专用概念混淆)
  • 第一章
  • 第二章(略)
  • 结束语
  • 引用
  • 感谢
  • 封底
    以上这些并不都是必须的,就算只有一章也没关系,仿佛一页A4纸打印好了扔在那里。
    Alt
    以下的函数,动态地创建了一个前言页面intro.xhtml。然后把’nav’和这个前言页面,加入到书脊。具体解释详见程序的注释
def add_intro_page(self):
    # title是页面的<title></title
    intro_page = epub.EpubHtml(title='-前言-', file_name='intro.xhtml', lang='zh')
    intro_page.content = '<p><h2>不可商用</h2></p><p>自学自用, 请勿传播</p>'
    self.book.add_item(intro_page)
    # spine 是 EPUB 书籍的主要内容部分, 它是一个列表, 包含了书籍的各个部分。这里我们先把前言部分添加到 spine 中
    # 每个spine的元素都是一个 EpubHtml 对象, 它代表了一个 HTML 页面,包含了页面的标题、内置文件名和内容等信息
    # 当 nav 出现在 spine 列表中时,通常表示导航文档(Navigation Document)。在 EPUB 3 规范中,导航文档是 nav.xhtml,
    # 它为读者提供了一种在电子书中进行导航的方式,类似于目录。
    self.spine = ['nav', intro_page]

封面 set_cover

就是一本书的封面的图像
alt

def set_book_cover(self, cover_image_path):
    # 如果封面图像路径为空, 使用默认封面图像
    if not cover_image_path:
        cover_image_path = "bg.png"
    # set_cover 函数用于设置书籍的封面图像。它接受三个参数:
    # 第一个参数是封面图像的文件路径,第二个参数是封面图像的二进制内容,
    # 第三个参数 False 是 create_thumbnail 参数。它是一个布尔值,
    # 用于指示是否要为封面图片创建缩略图。缩略图可以用于在app的书架里使用
    self.book.set_cover(cover_image_path, open(cover_image_path, 'rb').read(), False)

目录 toc

这个目录 toc,不是nav.xhtml那个页面,而是整个epub文档的内部逻辑。
主要靠epub.link来实现。
举个例子:
你家住在“长安街8号院8号楼808室”这是个内部逻辑,是派出所登记这个房子的一个编码。
而你家房门上有个牌子,上面写着8-808, 这只是一个牌子.即便它掉下来了,没有了,也不影响派出所里的逻辑

def add_toc(self):  # toc 目录
    # 先连接上前言部分, 然后再连接上各个章节
    toc = [epub.Link(href='intro.xhtml', title='++前言++', uid='intro***')]
    for chapter_filename, chap_title in self.book_info['chapters_filelist']:
        chapter_link = epub.Link(href=chapter_filename, title=f'++{chap_title}++')
        toc.append(chapter_link)
    self.book.toc = tuple(toc)

ncx / nav

ncx只限于epub2.0标准, 其他的我也不知道了. 请自行搜索.

def add_nav(self):
    # self.book.add_item(epub.EpubNcx())
    self.book.add_item(epub.EpubNav(file_name='mynav.xhtml', title='~~目录~~'))

反正得加上这么一句话.

#类和json配置文件

"""
读取json配置文件,然后把几个xhtml文件合并为epub的python库。配置文件里包含了书名、作者、封面图像路径、各个章节的路径和章节名称。
"""
from ebooklib import epub
import json

class EpubBookCreator:
    def __init__(self, book_info_json):
        self.book_info = book_info_json
        self.book = epub.EpubBook()
        self.book.set_identifier('id123456')
        self.book.set_language('zh')
        self.book.set_title(book_info_json['book_name'])
        self.book.add_author(book_info_json['book_auth'])
        self.set_book_cover(book_info_json.get("book_cover", "bg.png"))
        self.add_css()
        self.add_intro_page()
        self.add_chapters()
        self.add_toc()
        self.add_nav()

    def set_book_cover(self, cover_image_path):
        # 如果封面图像路径为空, 使用默认封面图像
        if not cover_image_path:
            cover_image_path = "bg.png"
        # set_cover 函数用于设置书籍的封面图像。它接受三个参数:
        # 第一个参数是封面图像的文件路径,第二个参数是封面图像的二进制内容,第三个参数 False 是 create_thumbnail 参数。
        # 它是一个布尔值,用于指示是否要为封面图片创建缩略图。缩略图可以用于在app的书架里使用
        self.book.set_cover(cover_image_path, open(cover_image_path, 'rb').read(), False)

    def add_css(self):
        css_text = '''
            @namespace epub "http://www.idpf.org/2007/ops";    
            body { font-family: "Times New Roman", Times, serif;}    
            p {text-indent: 2em; /* 设置段落首行缩进 */   margin-top: 0;  margin-bottom: 0.5em;}    
            '''
        # 创建一个 CSS 文件对象
        # epub.EpubItem 用于创建一个 EPUB 项目, 这里是一个 CSS 文件。它接受四个参数:
        # uid: 项目的唯一标识符  # file_name: 项目的文件名内置于epub里  # media_type: 项目的媒体类型, 这里是 "text/css"
        # content: 项目的内容, 这里是 CSS 样式文本
        style = epub.EpubItem(uid="style", file_name="style/mystyle.css", media_type="text/css", content=css_text)
        self.book.add_item(style)

    def add_intro_page(self):
        # title是页面的<title></title
        intro_page = epub.EpubHtml(title='-前言-', file_name='intro.xhtml', lang='zh')
        intro_page.content = '<p><h2>不可商用</h2></p><p>自学自用, 请勿传播</p>'
        self.book.add_item(intro_page)
        # spine 是 EPUB 书籍的主要内容部分, 它是一个列表, 包含了书籍的各个部分。这里我们先把前言部分添加到 spine 中
        # 每个spine的元素都是一个 EpubHtml 对象, 它代表了一个 HTML 页面,包含了页面的标题、内置文件名和内容等信息
        # 当 nav 出现在 spine 列表中时,通常表示导航文档(Navigation Document)。在 EPUB 3 规范中,导航文档是 nav.xhtml,
        # 它为读者提供了一种在电子书中进行导航的方式,类似于目录。
        self.spine = ['nav', intro_page]

    def add_chapters(self):
        for chapter_filename, chapter_title in self.book_info['chapters_filelist']:  # 按列表顺序取得各个章节的文件名和标题
            content = open(chapter_filename, 'r', encoding='utf-8').read()
            epub_chapter = epub.EpubHtml(title=chapter_title, file_name=chapter_filename, lang='zh')
            epub_chapter.content = f'{content}'
            self.book.add_item(epub_chapter)
            self.spine.append(epub_chapter)
        self.book.spine = self.spine

    def add_toc(self):  # toc 目录
        # 先连接上前言部分, 然后再连接上各个章节
        toc = [epub.Link(href='intro.xhtml', title='++前言++', uid='intro***')]
        for chapter_filename, chap_title in self.book_info['chapters_filelist']:
            chapter_link = epub.Link(href=chapter_filename, title=f'++{chap_title}++')
            toc.append(chapter_link)
        self.book.toc = tuple(toc)

    def add_nav(self):
        # self.book.add_item(epub.EpubNcx())
        self.book.add_item(epub.EpubNav(file_name='mynav.xhtml', title='~~目录~~'))

    def save(self):
        epub_path = f'{self.book_info["book_name"]}.epub'
        epub.write_epub(epub_path, self.book, {})
        print(f"EPUB 文件已创建: {epub_path}")

if __name__ == '__main__':
    with open('book_info.json', 'r', encoding='utf-8') as f:
        json_book_info = json.load(f)
    epub_creator = EpubBookCreator(json_book_info)
    epub_creator.save()

有几个字段是爬虫用的,本程序用不到. chapter_*.xhtml 是本地文件

{
    "menu_file": "listbs.txt",
    "book_name": "书的名字",
    "book_auth": "作者",
    "txt_content_id": "acontent",
    "book_cover": "cover.jpg",
    "chapters_filelist": [
        [
            "chapter_0.xhtml",
            "第一章"
        ],
        [
            "chapter_1.xhtml",
            "第二章"
        ],
        [
            "chapter_2.xhtml",
            "第三章"
        ]
    ]
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值