EPUB檔案格式簡單解析
最近熱衷於看輕小說,奈何某些網站樣式排版屬實糟糕,移動端體驗極度不友好,實在無法忍受,於是希望能將網站內容爬取下來製作成EPUB格式的電子書。
拋開爬取網站內容不談,通過解析EPUB檔案後,大致掌握了EPUB檔案的基本格式內容。
EPUB檔案結構
EPUB檔案本質是一個zip壓縮檔案。
將EPUB檔案字尾改為zip解壓即可一窺真相。
使用tree命令檢視整個EPUB檔案的目錄結構和檔案,其中部分檔案被省略。
mimetype │ ├─META-INF │ container.xml │ └─OEBPS │ chapter0001.xhtml │ chapter0002.xhtml │ chapter0003.xhtml │ chapter0004.xhtml │ chapter0005.xhtml │ chapter0006.xhtml | ... │ content.opf │ toc.ncx │ └─images 39655.jpg 39656.jpg 39657.jpg ...
固有檔案
- mimetype
- META-INF/container.xml
mimetype
mimetype是一個文字檔案,內容固定為:application/epub+zip
META-INF/container.xml
其中rootfile的屬性full-path指定了此書的OPF檔案路徑。
<?xml version="1.0" encoding="UTF-8"?> <container xmlns="urn:oasis:names:tc:opendocument:xmlns:container" version="1.0"> <rootfiles> <rootfile full-path="OEBPS/content.opf" media-type="application/oebps-package+xml"/> </rootfiles> </container>
OPF
Open Package Format(OPF),即包檔案格式,其主要功能是用於組織 OPS 文件和提供相應的導航機制,並形成一個開放式的基於 XML 的打包文件,該文件的字尾名為 “.opf” 。
通過META-INF/container.xml
即可定位到OPF檔案。
檢視檔案內容,可以比較容易猜測每部分的作用。
<?xml version="1.0" encoding="UTF-8"?> <package xmlns="http://www.idpf.org/2007/opf" unique-identifier="bookId" version="2.0"> <metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf"> <dc:identifier id="bookId">urn:uuid:9bfb698f-dfa3-45ca-bea4-d0fbc2ead4f3</dc:identifier> <dc:language>en</dc:language> <dc:title>第一卷 虛偽的王國</dc:title> <meta content="cover-image" name="cover"/> </metadata> <manifest> <item href="toc.ncx" id="ncx" media-type="application/x-dtbncx+xml"/> <item href="chapter0001.xhtml" id="chapter0001.xhtml" media-type="application/xhtml+xml"/> <item href="chapter0002.xhtml" id="chapter0002.xhtml" media-type="application/xhtml+xml"/> <item href="chapter0003.xhtml" id="chapter0003.xhtml" media-type="application/xhtml+xml"/> <item href="chapter0004.xhtml" id="chapter0004.xhtml" media-type="application/xhtml+xml"/> <item href="chapter0005.xhtml" id="chapter0005.xhtml" media-type="application/xhtml+xml"/> <item href="chapter0006.xhtml" id="chapter0006.xhtml" media-type="application/xhtml+xml"/> ... <item href="images/39655.jpg" id="cover-image" media-type="image/jpeg"/> </manifest> <spine toc="ncx"> <itemref idref="chapter0001.xhtml"/> <itemref idref="chapter0002.xhtml"/> <itemref idref="chapter0003.xhtml"/> <itemref idref="chapter0004.xhtml"/> <itemref idref="chapter0005.xhtml"/> <itemref idref="chapter0006.xhtml"/> ... </spine> </package>
metadata
EPUB檔案元資料
dc:identifier
書本的唯一識別符號,需要和ncx檔案中的identifier一致,雖然不一致也沒問題。
dc:language
書本使用的語言 不是很重要。
dc:title
整本書的書名,重要性不言而喻。
meta
通過對部分EPUB進行解壓,目前只發現設定封面的meta
<meta content="cover-image" name="cover"/>
一般沒有需求不更改,如何設定封面檢視下文。
manifest
整本書的清單檔案,一般會列出ncx檔案和小說正文檔案以及封面。
item
清單檔案專案。
- href 檔案的相對路徑
- id 專案ID
- media-type 檔案的MIME型別
正文網頁檔案
一般格式都為XHTML,可以使用樣式圖片音訊各種各樣的資源。
指定封面圖片
- metadata中包含
name
為cover的meta
標籤
<meta content="cover-image" name="cover"/>
- manifest中包含id為上述meta的content屬性的item
- 通過設定item的
href
即可指定封面路徑
<item href="images/39655.jpg" id="cover-image" media-type="image/jpeg"/>
spine
翻譯成中文就是書脊,通過引用的順序來指定閱讀順序。
例如上文檔案依次列出了chapter0001、chapter0002等,閱讀完chapter0001就會開始閱讀chapter0002。
itemref
引用的manifest中的檔案,只需要引入正文網頁檔案。
- idref 需要與manifest中itme的id對應 代表此檔案
- linear 表明該項是作為線性閱讀順序中的一項,與先後順序無關,預設為yes
NCX
NCX是Navigation Content eXtended的縮寫,用於表示本書的目錄。
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/">
<head>
<meta content="urn:uuid:9bfb698f-dfa3-45ca-bea4-d0fbc2ead4f3" name="dtb:uid"/>
<meta content="1" name="dtb:depth"/>
<meta content="0" name="dtb:totalPageCount"/>
<meta content="0" name="dtb:maxPageNumber"/>
</head>
<docTitle>
<text>第一卷</text>
</docTitle>
<navMap>
<navPoint id="navPoint-1" playOrder="1">
<navLabel>
<text>插圖</text>
</navLabel>
<content src="chapter0001.xhtml"/>
</navPoint>
<navPoint id="navPoint-2" playOrder="2">
<navLabel>
<text>序章</text>
</navLabel>
<content src="chapter0002.xhtml"/>
</navPoint>
<navPoint id="navPoint-3" playOrder="3">
<navLabel>
<text>第一章 前世</text>
</navLabel>
<content src="chapter0003.xhtml"/>
</navPoint>
<navPoint id="navPoint-4" playOrder="4">
<navLabel>
<text>第二章 異世界</text>
</navLabel>
<content src="chapter0004.xhtml"/>
</navPoint>
<navPoint id="navPoint-5" playOrder="5">
<navLabel>
<text>第三章 冤罪</text>
</navLabel>
<content src="chapter0005.xhtml"/>
</navPoint>
<navPoint id="navPoint-6" playOrder="6">
<navLabel>
<text>第四章 入學王立學院</text>
</navLabel>
<content src="chapter0006.xhtml"/>
</navPoint>
<navPoint id="navPoint-7" playOrder="7">
<navLabel>
<text>第五章 五年後</text>
</navLabel>
<content src="chapter0007.xhtml"/>
</navPoint>
<navPoint id="navPoint-8" playOrder="8">
<navLabel>
<text>第六章 野外演習</text>
</navLabel>
<content src="chapter0008.xhtml"/>
</navPoint>
<navPoint id="navPoint-9" playOrder="9">
<navLabel>
<text>第七章 虛偽的真相</text>
</navLabel>
<content src="chapter0009.xhtml"/>
</navPoint>
<navPoint id="navPoint-10" playOrder="10">
<navLabel>
<text>末章</text>
</navLabel>
<content src="chapter0010.xhtml"/>
</navPoint>
<navPoint id="navPoint-11" playOrder="11">
<navLabel>
<text>後記</text>
</navLabel>
<content src="chapter0011.xhtml"/>
</navPoint>
<navPoint id="navPoint-12" playOrder="12">
<navLabel>
<text>特典 淑女空腹狀態</text>
</navLabel>
<content src="chapter0012.xhtml"/>
</navPoint>
<navPoint id="navPoint-13" playOrder="13">
<navLabel>
<text>特典 霧雨茫茫相思相愛傘</text>
</navLabel>
<content src="chapter0013.xhtml"/>
</navPoint>
<navPoint id="navPoint-14" playOrder="14">
<navLabel>
<text>特典 貴族千金們的茶會</text>
</navLabel>
<content src="chapter0014.xhtml"/>
</navPoint>
</navMap>
</ncx>
meta
dtb:uid
<meta content="urn:uuid:9bfb698f-dfa3-45ca-bea4-d0fbc2ead4f3" name="dtb:uid"/>
這個和opf中的dc:identifier應該保持一致,不一致倒也沒什麼問題。
depth、totalPageCount和maxPageNumber
<meta content="1" name="dtb:depth"/>
<meta content="0" name="dtb:totalPageCount"/>
<meta content="0" name="dtb:maxPageNumber"/>
對於電子書不需要進行修改,使用這幾個值就OK。
docTitle
<docTitle>
<text>第一卷</text>
</docTitle>
姑且認為應該與opf中的dc:title一致,書名以opf中的為準。
navPoint
<navPoint id="navPoint-1" playOrder="1">
<navLabel>
<text>插圖</text>
</navLabel>
<content src="chapter0001.xhtml"/>
</navPoint>
整書的目錄,每個navPoint代表目錄中的一項,包含標題和檔案路徑。
一個EPUB有以上這些檔案就能被識別,通過建立檔案然後壓縮就可以完成一個EPUB檔案的建立。
完成的專案
最後提一下已經完成的開頭的專案: linovel-downloader