mobi (Python)
| Language | Python 3.9+ |
|---|---|
| License | GPL-3.0-only |
| Repository | github.com/iscc/mobi |
| Documentation | README |
| Depends on | loguru, standard-imghdr |
| Read / write | yes / no (MOBI 6, KF8/AZW3, hybrid, Print Replica; unencrypted only) |
mobi is a fork of KindleUnpack, the standard tool for taking Kindle files apart, without its GUI and packaged for PyPI. Its one public function, mobi.extract(), unpacks a book into a temporary folder and returns the path to the most useful result:
- an EPUB rebuilt from the KF8 part, for AZW3 and hybrid
.mobifiles; - an HTML file (
book.html) with images, for MOBI 6 files; - a PDF for Print Replica (
.azw4) books.
It decodes PalmDOC and HUFF/CDIC text and reconstructs the KF8 source with its CSS, fonts and table of contents. It doesn’t decrypt DRM books. The GPL-3.0 license applies to programs that you distribute with it.
Installation#
pip install mobi
The package also installs the mobiunpack command, which is the original KindleUnpack command line.
Basic usage: convert MOBI or AZW3 to EPUB#
import shutil
import mobi
tempdir, filepath = mobi.extract("book.azw3")
try:
print("unpacked to", filepath) # .epub, .html or .pdf
if filepath.endswith(".epub"):
shutil.copy(filepath, "book.epub")
finally:
shutil.rmtree(tempdir) # extract() leaves the folder for you to delete
How to extract text from a MOBI file#
Unpack, then read the HTML or EPUB that extract returns:
import shutil
import zipfile
import mobi
from bs4 import BeautifulSoup # pip install beautifulsoup4
def mobi_text(path):
tempdir, filepath = mobi.extract(path)
try:
if filepath.endswith(".html"): # MOBI 6
with open(filepath, "rb") as f:
return BeautifulSoup(f.read(), "html.parser").get_text("\n", strip=True)
if filepath.endswith(".epub"): # KF8
parts = []
with zipfile.ZipFile(filepath) as z:
for name in sorted(z.namelist()):
if name.endswith((".xhtml", ".html")):
parts.append(BeautifulSoup(z.read(name), "html.parser").get_text("\n", strip=True))
return "\n\n".join(parts)
return "" # PDF from a Print Replica book
finally:
shutil.rmtree(tempdir)
print(mobi_text("book.mobi")[:500])
For the exact chapter order of the EPUB, read it with EbookLib and follow the spine.
How to unpack a book from a file object#
extract also accepts an open binary file (it copies it to the temporary folder first):
with open("book.mobi", "rb") as f:
tempdir, filepath = mobi.extract(f)
How to get all unpacked parts (images, OPF, both MOBI 6 and KF8)#
Call KindleUnpack directly to choose the output folder and the EPUB version:
from mobi.kindleunpack import unpackBook
unpackBook("book.mobi", "out", epubver="3") # epubver: "2", "3", "A" (automatic) or "F"
# out/mobi7/ : MOBI 6 HTML and images
# out/mobi8/ : KF8 source and the rebuilt EPUB
The same from the command line: mobiunpack --epub_version=3 book.mobi out.
Tips#
extractraises an exception for DRM-protected or damaged books, andValueErrorwhen it finds no EPUB, HTML or PDF output; wrap it intrywhen processing many files.- Each call writes the whole unpacked book to disk. If
extractraises, its temporary folder (namedmobiex...in the system temp directory) stays behind; clean those up in batch jobs.