PythonのライブラリEbookLibでEPUBを扱ってみる – データ抽出 –

2021.12.13

pdfのデータからEPUBを作成することを目標に最近はpdfのテキスト抽出について色々と試してみましたが、 今回はプログラムからEPUBを作る ということを試したいと思います。

今回使用するEbookLibは、EPUB2/EPUB3のファイルをプログラムから読み書きすることができるようになるPythonライブラリです。

ドキュメントによると、表紙、目次、背表紙、ガイド、メタデータなどをサポートしているとのことなで、色々と試していきます。

インストール

pipを使ってインストールします。

pip install ebooklib

EPUBの読み込み

EPUB3のサンプルが公開されているので、使わせてもらいます。

import ebooklib
from ebooklib import epub

book = epub.read_epub('accessible_epub_3.epub')

ebooklib.epub.read_epub('ファイル名')でebooklib.epub.EpubBookクラスのインスタンスが返ってきます。

Metadata

Metadataは、

  • EPUBの内部カタログに使用し、(例えば、本棚に提示するなど)ユーザーのために利用可能にするリーディングシステムのためのメタ情報の最小セットを提供する。
  • レンディションのコンテンツ(例えば、固定レイアウト プロパティ)のレイアウトおよび表示をコントロールするために必要な全てのレンダリングのメタデータへのアクセスを提供する

といった2つの主要な要素があります。

例)

<package … unique-identifier="pub-id">
    …
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
<meta property="dcterms:modified">2012-10-24T15:30:00Z</meta>
<dc:identifier id="pub-identifier">urn:isbn:9781449328030</dc:identifier>
<dc:title id="pub-title">Accessible EPUB 3</dc:title>
<dc:language id="pub-language">en</dc:language>
<dc:creator id="pub-creator12">Matt Garrish</dc:creator>
<dc:contributor>O’Reilly Production Services</dc:contributor>
<meta property="schema:accessMode">textual</meta>
</metadata>
    …
</package>

ebooklib.epub.EpubBook.get_metadata() でEPUBのメタデータを取得できます。

book.metadata

# DC名前空間
book.get_metadata('DC', 'identifier')
book.get_metadata('DC', 'title')
book.get_metadata('DC', 'language')

# カスタムメタデータ
book.get_metadata('OPF', None)

このようにメタデータを取得することができます。

カスタムメタデータにアクセスするときは、名前空間「OPF」を使用することで取得できるとドキュメントに書かれていましたが、取得できていないデータもありました。

Item

画像、ビデオ、サウンド、スクリプと,html,cssファイルなどはアイテムです。

例)

<manifest>
        <item id="htmltoc" properties="nav" media-type="application/xhtml+xml" href="bk01-toc.xhtml"/>
        <item media-type="text/css" id="epub-css" href="css/epub.css"/>
        <item media-type="text/css" id="epub-tss-css" href="css/synth.css"/>
        <item id="cover" href="cover.xhtml" media-type="application/xhtml+xml"/>
        <item id="cover-image" properties="cover-image" href="covers/9781449328030_lrg.jpg" media-type="image/jpeg"/>
        <item id="id-id2442754" href="index.xhtml" media-type="application/xhtml+xml"/>
    …
</manifest>

現在は以下のアイテムタイプが定義されていて、 ebooklib.epub.EpubBook.get_items_of_type() でアイテムをfetchすることができます。

  • ITEM_UNKNOWN
  • ITEM_IMAGE
  • ITEM_STYLE
  • ITEM_SCRIPT
  • ITEM_NAVIGATION
  • ITEM_VECTOR
  • ITEM_FONT
  • ITEM_VIDEO
  • ITEM_AUDIO
  • ITEM_DOCUMENT
  • ITEM_COVER
  • ITEM_SMIL

また、ebooklib.epub.EpubBook.get_items()で全てのアイテムを取得できます。

## 全てのアイテム
book.get_items()

## 画像
book.get_items_of_type(ebooklib.ITEM_IMAGE)

## カバー画像
book.get_items_of_type(ebooklib.ITEM_COVER)

## ナビ
book.get_items_of_type(ebooklib.ITEM_NAVIGATION)

IDやファイル名でもfetchすることができます

cover_image = book.get_item_with_id('cover-image')
index = book.get_item_with_href('index.xhtml')
print(cover_image)
print(index)

objectが返ってきますが、コンテンツの中身を取得する場合は、ebooklib.epub.EpubItem.get_content()を使用します。

HTMLの場合

index = book.get_item_with_href('index.xhtml')
index.get_content()
index.get_body_content()

ebooklib.epub.EpubHtml.get_body_content() を使用すると、HTMLのbody部分のみを取得することが可能です

ファイル名を取得する場合、ebooklib.epub.EpubItem.get_name()を使用します。

cover_image = book.get_item_with_id('cover-image')
cover_image.get_name()

from ebooklib.utils import debug
navi = book.get_items_of_type(ebooklib.ITEM_IMAGE)
for x in navi:
  debug(x.get_name())

最後に

PythonのライブラリEbookLibを使ってEPUBを読み込んで中のデータを取得してみました。 EbookLibはかなりシンプルな作りなので扱いやすいと思います。

次回はこのライブラリを使ってEPUBの作成を試してみようと思います。

参考ドキュメント: http://docs.sourcefabric.org/projects/ebooklib/en/latest/index.html