Watch at Ease看見世界,讀懂生活。

科技 · 實用指南

EPUB 報「no item named」?改書前先追查缺失的 ZIP 成員

缺指令碼、缺章節和大小寫不符,都可能觸發同一種 KeyError。四份受控樣本說明:ZIP 檢查通過,不代表 EPUB 內容完整。

原創示意圖:四份原創 EPUB 均通過 ZIP CRC 檢查,但只有對照樣本能被 EbookLib 0.20.0 載入;其餘分別在指令碼、spine 章節或大小寫不符路徑上失敗。
原創示意圖:四份原創 EPUB 均通過 ZIP CRC 檢查,但只有對照樣本能被 EbookLib 0.20.0 載入;其餘分別在指令碼、spine 章節或大小寫不符路徑上失敗。 Watch at Ease

EPUB 報錯稱某個路徑沒有對應項目,表示一次壓縮檔成員查找失敗,並不能說明缺的是章節、指令碼,還是參照拼字有誤。修改前,先保留原檔與錯誤路徑全文。

我們在 Python 3.12.14、EbookLib 0.20.0、lxml 6.1.3 中測試四份原創本機 EPUB 3。對照樣本能載入;移除清單宣告的指令碼、移除書脊中的第二章,或把章節參照改一個大寫字母,均觸發 KeyError。四份壓縮檔的 ZipFile.testzip() 全部通過,稽核期間輸入檔案雜湊均未改變。

這是套件內查找測試,不能證明對照樣本完全符合 EPUB 標準,也不能證明裝置會正確顯示這些檔案。我們沒有執行 EPUBCheck、Calibre、EpubSplit 或圖形閱讀器。本文提供的實際補充,是把同一異常分流到不同排查方向的對照。

從套件文件沿參照追到壓縮檔

先列出壓縮檔成員,不解壓縮覆寫檔案。Python 指令為 python -m zipfile -l book.epub。讀取 META-INF/container.xml,確定套件文件位置。樣本中是 OEBPS/package.opf,因此 manifest 的 Text/chapter2.xhtml 指向 OEBPS/Text/chapter2.xhtml。

記錄 manifest ID、原始 href、媒體類型、解析後的成員名稱、是否精確存在,以及 spine 位置。W3C 規定套件文件是其中 URL 的基準,容器名稱區分大小寫。測試僅使用簡單本機路徑;遠端資源、編碼名稱、片段、多重呈現版本或錯誤 XML,應遵循對應 URL 與套件規則,不能憑猜測拼接檔案系統路徑。

區分本文缺失與參照不相符

缺章節樣本中,c2 指向不存在的 OEBPS/Text/chapter2.xhtml,位於 spine 第 2 位。不要補一個空章節,或跳過異常後把結果標為完整。應取得更正後的來源檔,或由獲授權的製作者還原真實本文與相關連結。

大小寫不符樣本中,manifest 要求 Text/Chapter1.xhtml,壓縮檔實際包含 Text/chapter1.xhtml。稽核列出大小寫不同的候選項,沒有自動選取或重新命名。定向修正前,須核對全部參照與製作者原意;近似相符是線索,不是等價證明。

不在 spine 中的指令碼,也不能自動丟棄

移除 OEBPS/js/unused.js 同樣讓 EbookLib 停止,儘管兩份 spine 章節仍在壓縮檔內。在合成樣本裡,我們知道指令碼未被使用,因為每個檔案都是我們建立的;他人書籍中不在 spine 的指令碼,仍可能被本文參照或支援某項功能。

追查相依關係,請製作者還原資源,或明確移除過時宣告與其參照。不要把缺失的本機檔歸為允許的遠端資源,不要下載同名指令碼補進去,也不要攔截所有 KeyError 後繼續。上游問題 281 已經說明此類 manifest 載入失敗,這不是本文新發現的機制。

分別驗收 ZIP、出版物結構與最終交付

testzip() 檢查已存成員的 CRC 與檔頭,不知道出版物原本應包含哪些成員。四份樣本均傳回 None,包括缺章節樣本。對照樣本被 EbookLib 載入,只表示該剖析器在測試選項下接受了它,不代表完全符合 EPUB 標準。

Calibre 文件中的 Tools → Check book 已能回報失效連結與 OPF 問題,W3C 也建議使用 EPUBCheck 等符合性檢查器。對工作副本使用這些既有方法,並保留報告。獲授權修正後,重跑最初失敗的操作,核對預期章節順序與本文,再測試所需閱讀流程。保留原件並記錄未解決資源;重試變綠,不能單獨證明文字與功能都沒有遺失。

原創示意圖:沿 container.xml、套件文件、manifest ID 與 href,追到精確的壓縮檔成員與 spine 位置;成員缺失或近似候選都需要記錄決定,不能自動跳過。
原創示意圖:沿 container.xml、套件文件、manifest ID 與 href,追到精確的壓縮檔成員與 spine 位置;成員缺失或近似候選都需要記錄決定,不能自動跳過。 Watch at Ease