kindle本→PDF

Kindle本をPDFに変換する

software

  • KindleForPC-installer-2.3.70840.exe
  • calibre-64bit-8.5.0.msi
  • DeDRM(10.0.9)
  • Gather KFX-ZIP(from KFX Input)(2.26.2)

kindleを開き、「ヘルプ」→「バージョン情報」からバージョンが2.4.0であることを確認

「ツール」→「オプション」→「一般」から自動更新のチェックボックスを外しておく

kindleから本をダウンロードしたら、calibreを開く

ZIPファイルのまま選択

2つインストールしたら再起動

「本を追加」→
C:\Users\ユーザ名\Documents\My Kindle Content\からazw形式のファイルをインポート

右クリックで選択して「本を変換」

左上が「KFX」であることを確認し、右は「PDF」にする
問題なければ「OK」を選択

変換後のPDFファイルは、C:\Users\ユーザ名\calibreライブラリ(あるいはcalibreインストール時に選択したフォルダ)に格納されている

画像本の場合

そのままだと余白が大きいので、

zipファイルの並び順修正

zipファイルとして出力するとページの並びがバラバラなので

import os
import re
import sys
import tempfile
import shutil
import zipfile
from pathlib import Path
from bs4 import BeautifulSoup

def get_first_html(files):
    """最初に参照するhtml, xhtmlを探す"""
    html_path = find_list(".html", files)
    if html_path is None:
        htmls = find_list(".xhtml", files)
        html_path = htmls[0] if htmls is not None else None

    return html_path

def get_title_from_html(html):
    """htmlファイルから <meta name="DC.title" content="title"> を抽出"""
    content = html.read_text(encoding="utf-8")
    soup = BeautifulSoup(content, "html.parser")
    tag = soup.find("meta", attrs={"name": "DC.title"})
    title = tag.get("content") if tag else "None title"
    return sanitize_filename(title)

def sanitize_filename(filename):
    """ファイル名に使えない文字を置換する"""
    table = str.maketrans({
        '/': '/',
        '\\': '¥',
    })
    return filename.translate(table)

def analyze_html(html):
    """htmlから次ページのhrefと現在ページのimgを抽出"""
    content = html.read_text(encoding="utf-8")
    soup = BeautifulSoup(content, "html.parser")

    # <a href="---" class="calibreANext">
    next_a = soup.find("a", class_="calibreANext")
    next_href = next_a.get("href") if next_a else None

    # <img src="---">
    img = soup.find("img")
    img_src = img.get("src") if img else None

    return next_href, img_src

def find_list(x, lists):
    """listsからxを含む項目lを取り出す"""
    for l in lists:
        if x in str(l):
            return l
    return None

def convert2cbz(input_path, output_ext="cbz"):
    """変換本体"""
    with tempfile.TemporaryDirectory() as tmpdir:
        tmpdir = Path(tmpdir)

        # 解凍
        with zipfile.ZipFile(input_path, 'r') as zip_ref:
            zip_ref.extractall(tmpdir)

        # ファイルリストを取得
        files = list(tmpdir.glob("**/*"))

        # HTMLからタイトル抽出
        first_html = get_first_html(files)
        output_title = get_title_from_html(first_html)

        # HTMLのnext pageを辿ってimgをoutput_listに追加
        output_list = []
        prefix, midstr = "image", "-"
        cnt = 1 # 連番用カウンター
        cnt_len = len(str(len(files))) # 連番桁数=ファイル数の桁数
        next_html, img_name = analyze_html(first_html)
        while True:
            # get current html_path, img_path & next_html name
            html_path = find_list(next_html, files)
            next_html, img_name = analyze_html(html_path)
            ext = os.path.splitext(img_name)[1]
            img_path = find_list(img_name, files)

            # set new_path for img
            postfix = str(cnt)
            postfix = postfix.zfill(cnt_len)
            new_name = prefix + midstr + postfix + ext
            new_path = tmpdir / new_name

            # copy & rename img file
            shutil.copy(img_path, new_path)
            output_list.append(new_path)
            if next_html is None:
                break
            cnt += 1

        # cover(表紙)は別枠で追加
        for f in files:
            if "cover" in f.name.lower():
                cover_path = tmpdir / os.path.basename(f)
                shutil.copy(f, cover_path)
                output_list.insert(0, cover_path)

        # zip/cbz作成
        output_path = f"{output_title}.{output_ext}"
        with zipfile.ZipFile(output_path, 'w', zipfile.ZIP_DEFLATED) as out_zip:
            for f in output_list:
                out_zip.write(f, f.name)

        print(f"✅ 出力完了: {output_path}")

# 実行部
if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("usage: python conv_kindle_cbz.py <input.epub|zip> [cbz|zip]")
        sys.exit(1)

    input_file = sys.argv[1]
    ext = sys.argv[2] if len(sys.argv) > 2 else "cbz"

    if not os.path.isfile(input_file):
        print(f"指定されたファイル {input_file} が見つかりません。")
        sys.exit(1)

    convert2cbz(input_file, ext)

Kindle2.7.1

kindle2.4.0だと最近の本がダウンロードできないので別の方法を使う
以下の日本語訳になります
https://gall.dcinside.com/mgallery/board/view/?id=lilyfever&no=1716552

Kindle2.8でも動く可能性はあるが、Kindle2.7.1のほうが安定

software

KFX Inputは「環境設定」→「プラグイン」→「新規プラグインを取得]
右上の「名前で絞込み」から"KFX"などと打てばリストに表示されるので選択した状態で右下の「インストール」を押下
Outputは無くてよい

a15714ab041eb360be3335625683746f0153452ed6a7ea89d73166f69c1ccd6e97e0667f2a088a3a0a444f1d4a

抽出をしたい本をKindle PCアプリから全てダウンロードしておく

ダウンロードした本のフォルダをコピー
a15714ab041eb360be3335625683746f0153452ed6a7ea89d73160f29d1ccd6ee74f8ab3072e1490e0194c56c0

Cドライブ等に適当な空フォルダを作り、そこにペースト
ファイル名はasdfとする(あとでcmdから指定するので、同じようにした方が楽)

a15714ab041eb360be3335625683746f0153452ed6a7ea89d73160f59915cd6edac29b37e1508e031e778e57db

タスクマネージャを開く(Ctrl+shift+esc)

Kindle(32ビット)を右クリックし、「メモリダンプファイルの作成」をクリック


作成したらなんか聞かれるので、「ファイルの場所を開く」をクリック

ファイル名を指定して実行(Windows+R)で%temp%と入力しても開ける
a15714ab041eb360be3335625683746f0153452ed6a7ea89d73667f59916cd6e64466cd78856888a7a9ea99e9b

該当するKindle.DMPまたはKindle(n).DMPファイルの場所が分かるようにしておいて、

ファイル名を指定して実行(Windows+R)から

%localappdata%\Amazon\Kindle\application

(これで開かない場合は、Kindleがインストールされているフォルダを探してください)

tempフォルダ内のKindle.DMPファイルをカットして開いたapplicationフォルダ内にペースト
(もし名前がKindle(n).DMPの場合は、applicaitonフォルダに入れた後、Kindle.DMPにリネーム)

さらに、ダウンロードしたKRFKeyExtractorを解凍するとKRFKeyExtractor.exeがあるのでこれもapplicationフォルダ内にペースト

applicationフォルダ内でcmdを開く

cmdウィンドウに以下の命令を貼り付ける。

KRFKeyExtractor.exe Kindle.DMP "C:\asdf" kindlekey.file 

エラーが出ても無視して待機

a15714ab041eb360be3335625683746f0153452ed6a7ea89d73161f6981ccd6e03ee0a49ae6210e214b80b8ed3 

a15714ab041eb360be3335625683746f0153452ed6a7ea89d73161f89d13cd6ec5890228fcc8d0aec54dac36a69f 

以下のように出ると完了

a15714ab041eb360be3335625683746f0153452ed6a7ea89d73161f89911cd6e8a31f271a623adb6d76423e0a9 

calibreを開き、「環境設定」→「プラグイン」から、
DeDRMを検索しDeDRM(10.0.12) ダブルクリック

以下のようなウィンドウが出るので、applicationフォルダ内のkindkey.fileを読み込む

後で別の本を抽出するときは、keyfileをapplicationフォルダに同じ名前にすると、キャリバーにもすぐに適用されます。

Q. キャリバー書誌で application フォルダの keyfile を適用するとき、どのようにそのフォルダに行きますか?

A. ファイルエクスプローラのパスの右側の空白をクリックするか、コントロール+Lを押すとそのフォルダのパスをコピーできます。

application フォルダからパスをコピーしておき、キャリバーで keyfile を適用するとき、同じようにパスに貼り付けてくれれば、そのフォルダに行くことができます。

a15714ab041eb360be3335625683746f0153452ed6a7ea89d73166f99c1ccd6e62eee83904eab58e7c579f5364 

次に、確認 - 適用 - 閉じる

抽出したい本のazwファイルをキャリバーに入れれば、従来の方法で抽出可能

2回目以降

My Kindle Content内を全選択してasdfにコピー
コピー中に聞かれるので、重複するファイルをスキップする

Windows+Rで

cmd /K cd /d "%localappdata%\Amazon\Kindle\application"

cmdに以下を打ち込む

del kindlekey.file
del Kindle.DMP

kindleを開き、タスクマネージャからメモリダンプファイルを作成して
application内に移動

%localappdata%\Amazon\Kindle\application

先ほど開いたcmdで以下を入力

KRFKeyExtractor.exe Kindle.DMP "C:\asdf" kindlekey.file

これでkindlekey.fileが更新されるのでcalibreで本を追加して変換