この記事では、Kindle Cloud Reader 上で表示された本を自動でページ送りしながらスクリーンショットを撮影し、最終的に1つのPDFにまとめる Python ツールの設計と実装について詳しく解説します。
unikarei/Kindle2PDF: Convert a Kindle book to PDF using screenshots.
■実行方法: run_kindle_to_pdf.bat 実行
- 仮想環境(.venv)を有効化
- kindle_to_pdf.py を起動
- Chrome が立ち上がり Kindle Cloud Reader を開く
- 画面の指示に従ってログイン&本を開き、1ページ目・F11 全画面・ページめくり方向確認
- ターミナルで Enter を押すと、自動キャプチャと PDF 生成が始まる
なお、このツールは個人的なバックアップ用途のみを対象としており、Amazon の利用規約および著作権法の遵守を前提とします。
1. 概要とアーキテクチャ設計
1-1. ツールの目的
本ツールは、PCブラウザ版 Kindle Cloud Reader 上で本を1ページずつ表示しながら自動的にスクリーンショットを撮影し、それらの画像を1つの PDF にまとめることで「自分用の閲覧用PDF」を生成することを目的としています。
主な特徴は以下の通りです。
- Kindle Cloud Reader を Selenium で自動操作
- PyAutoGUI による画面キャプチャ(フルスクリーン、または任意領域)
- 画像を img2pdf ライブラリで結合し、1つのPDFを生成
- 設定ファイル config.json による柔軟な制御(ページ数、遅延、キャプチャ領域、ページめくり方向など)
- Windows 環境向けのバッチファイルでワンクリック実行
1-2. 全体構成
ディレクトリ構成は次のようになっています。
0104/
├── kindle_to_pdf.py # メインアプリケーション
├── set_screenshot_region.py # キャプチャ領域選択ツール
├── test_page_navigation.py # ページ送りテストツール
├── config.json # 設定ファイル(実際に使用)
├── config.example.json # 設定例
├── config.template.json # テンプレート
├── requirements.txt # Python依存ライブラリ
├── run_kindle_to_pdf.bat # メイン実行用バッチ
├── set_region.bat # 領域設定用バッチ
├── test_navigation.bat # ページ送りテスト用バッチ
├── README.md # ドキュメント
└── data/ # スクリーンショット保存先
中核となるのは kindle_to_pdf.py の KindleToPDF クラスで、次の責務を持ちます。
- 設定ファイルの読み込み
- Selenium WebDriver(Chrome)の起動と設定
- Kindle Cloud Reader 画面の案内・待機
- スクリーンショット撮影とファイル保存
- ページ送り処理(複数の方法をフォールバックしながら実行)
- 最後に PDF ファイルを生成
2. 開発環境と依存ライブラリ
2-1. 前提環境
このツールは次の環境をターゲットとしています。
- OS: Windows 10 / 11
- Python: 3.8 以上(開発時は 3.11 系)
- ブラウザ: Google Chrome 最新版
- ネットワーク接続: Kindle Cloud Reader にアクセス可能
2-2. 使用ライブラリ
requirements.txt にまとめられた主な依存は以下の通りです。
- selenium
Chrome を自動操作するためのブラウザ自動化フレームワーク。 - webdriver-manager
ChromeDriver を自動でダウンロード・更新し、パスの管理を簡略化。 - pyautogui
OSレベルのマウス・キーボード操作やスクリーンショット取得を行うためのライブラリ。 Pillow(PIL)
画像処理基盤。PyAutoGUIの内部依存でもあります。- img2pdf
PNG/JPEG などの画像から PDF を生成する軽量ライブラリ。
これらを一括インストールするには、プロジェクトフォルダで以下を実行します。
pip install -r requirements.txt
3. 実行手順とユーザーフロー
ここでは、一般ユーザーが実際にこのツールを使って Kindle 本を PDF 化するまでの流れを、できるだけ詳細に解説します。
3-1. 初回セットアップ
D:\usr8_work\...)に展開pip install -r requirements.txt
3-2. スクリーンショット領域の設定
3-1. 初回セットアップ
デフォルトでは、config.json の screenshot_region が null になっており、フルスクリーンでキャプチャする設定になっています。
もしブラウザ領域だけに限定したい場合は、GUIツール set_screenshot_region.py を使って領域を指定できます。
Windows では用意されたバッチファイルから起動できます。
set_region.bat をダブルクリック
GUIツールでは以下のような操作を行います。
- Kindle Cloud Reader で本のページを開いておく
- 領域設定ツールの指示に従って Enter キーを押す
- 画面が半透明になったら、マウスドラッグでキャプチャ領域を囲む
- ドラッグを離すと、config.json の screenshot_region が
[x, y, width, height]形式で自動更新される
全画面キャプチャで問題ない場合はこのステップは不要です。
3-3. Kindle Cloud Reader の準備
次に Kindle Cloud Reader 側の準備です。
- run_kindle_to_pdf.bat をダブルクリックしてメインツールを起動
- 自動的に Chrome が立ち上がり、
https://read.amazon.co.jp/kindle-library(日本)など、config.json で指定された URL が開く - 画面の指示に従って以下を手動で行う
- Amazon アカウントにログイン
- 対象の本を開く(通常は新しいタブで開く)
- 本の最初のページ(1ページ目)に移動
- F11 キーでブラウザをフルスクリーンにする(推奨)
- ページ送り方向を確認する
- 左矢印キーと右矢印キーを押してみて、「どちらで次のページに進むか」を確認
- それに合わせて config.json の page_turn_direction を
"left"または"right"に設定
- ターミナルに戻り、Enter キーを押すと自動キャプチャ処理が開始される
3-4. 自動キャプチャと PDF 生成
プログラムが開始されると、次のような処理が繰り返されます。
- 現在ページのスクリーンショットを取得し data フォルダに保存
- 設定された page_turn_direction にしたがってキー入力を送り、次のページへ移動
- page_delay 秒だけ待機してページ描画の完了を待つ
- total_pages に到達するまで 1–3 を繰り返す
- 全ページのスクリーンショット取得後、img2pdf により PDF ファイルを生成
delete_screenshotsがtrueの場合は、中間の PNG 画像を削除
最終的な PDF は、プロジェクトルートに kindle_book_YYYYMMDD_HHMMSS.pdf のような時刻付きファイル名で出力されるか、config.json の pdf_filename で明示的に指定したファイル名で出力されます。
4. 設定ファイル config.json の詳細
このツールの挙動はほぼすべて config.json によって制御されます。例として、以下のような構成になっています。
{
"total_pages": 196,
"output_dir": "data",
"pdf_filename": null,
"page_delay": 2.0,
"screenshot_region": null,
"fullscreen": true,
"delete_screenshots": false,
"page_turn_direction": "left",
"kindle_url": "https://read.amazon.co.jp/kindle-library",
"skip_url_open": false,
"use_chrome_profile": false,
"chrome_user_data_dir": "",
"_comment_total_pages": "キャプチャするページの総数を指定してください",
"_comment_output_dir": "スクリーンショットを保存するディレクトリ",
"_comment_pdf_filename": "出力PDFのファイル名
(nullの場合はタイムスタンプ付きの名前が自動生成されます)",
"_comment_page_delay": "ページ送り後の待機時間(秒)",
"_comment_screenshot_region": "スクリーンショットの領域 [x, y, width, height]。nullの場合は全画面(推奨)",
"_comment_fullscreen": "ブラウザを全画面で起動するかどうか",
"_comment_delete_screenshots": "PDF作成後にスクリーンショット画像を削除するかどうか",
"_comment_page_turn_direction": "ページめくり方向: 'left'=左矢印キー(次へ進む), 'right'=右矢印キー(次へ進む)",
"_comment_kindle_url": "Kindle Cloud ReaderのURL(日本: https://read.amazon.co.jp/kindle-library, 米国: https://read.amazon.com)",
"_comment_skip_url_open": "trueの場合、URLを開かずに既存のブラウザタブを使用(手動で本を開いておく必要あり)",
"_comment_use_chrome_profile": "既存のChromeプロファイルを使用するか(ログイン済みセッション利用)",
"_comment_chrome_user_data_dir": "Chromeのユーザーデータディレクトリ(例: C:/Users/YourName/AppData/Local/Google/Chrome/User Data)"
}
4-1. 主要な設定項目
| 項目 | 説明 | 典型的な値 |
|---|---|---|
| total_pages | キャプチャするページ数 | 本の総ページ数(例: 196) |
| output_dir | スクリーンショットの保存ディレクトリ | "data" |
| pdf_filename | 出力PDFのファイル名 | null で自動命名、または "mybook.pdf" |
| page_delay | ページ送り後の待機秒数 | 通常 1.5~3.0 秒程度 |
| screenshot_region | [x, y, width, height] 形式のキャプチャ領域 | null でフルスクリーン |
fullscreen | ブラウザを全画面表示で扱うか | true 推奨 |
delete_screenshots | PDF生成後に画像を削除するか | false から始めて検証後に true も可 |
| page_turn_direction | ページ送り方向。"left" または "right" | 本により異なる |
| kindle_url | Kindle Cloud Reader の URL | 日本なら https://read.amazon.co.jp/kindle-library |
skip_url_open | 既存のブラウザタブを使うか | 通常は false |
use_chrome_profile | 既存の Chrome プロファイルを使うか | ログイン済みプロファイル利用時に true |
chrome_user_data_dir | Chrome のユーザーデータディレクトリ | 環境に応じてパスを設定 |
4-2. ページめくり方向の扱い
Kindle の本によっては、「次ページ」が左矢印キー(←)だったり、右矢印キー(→)だったりします。この違いを吸収するために導入したのが page_turn_direction です。
- 左矢印キーで次ページに進む場合:
page_turn_direction: “left” - 右矢印キーで次ページに進む場合:
page_turn_direction: “right”
実装側では、この設定に応じて以下が切り替わります。
- Selenium に送るキー(Keys.ARROW_LEFT / Keys.ARROW_RIGHT)
- JavaScript で発火する
KeyboardEventのkey,code,keyCode - PyAutoGUI で送信するキー(pyautogui.press(‘left’) /
'right')
このように「方向」という抽象概念を1つの設定値で制御し、Selenium・JavaScript・PyAutoGUI の3層にわたって一貫して反映する設計になっています。
5. 内部処理フローの詳細
ここからは、kindle_to_pdf.py 内部の処理フローをもう少し低レベルに追いかけていきます。
5-1. 起動と設定読み込み
プログラム開始時に行う主な処理は次の通りです。
- config.json の読み込みとバリデーション
- 出力ディレクトリ(output_dir)の存在確認・必要に応じた作成
- Chrome の起動オプション構築
- ヘッドレスではなく通常モード
- 自動テスト検知回避のためのフラグ(
--disable-blink-features=AutomationControlledなど) - 必要であれば Chrome プロファイルディレクトリ指定
- webdriver-manager を用いて ChromeDriver を自動取得し、Selenium WebDriver を初期化
この段階でブラウザが起動し、kindle_url にアクセスします。
5-2. Kindle Cloud Reader 画面の案内とタブ切り替え
Kindle Cloud Reader は、本を選ぶと通常別タブでコンテンツビューが開かれます。そのため、次のようなロジックを組み込んでいます。
- kindle_url にアクセス直後に、ログインおよび本の選択をユーザーに促すメッセージをターミナルに表示
- Enter キー押下まで待機(この間にユーザーがログインし、本を開く)
- その間に新しいタブが開かれていれば、driver.window_handles をチェックして新タブに自動的に切り替える
- どのタブでもいいから本が開かれていそうなウィンドウを window.focus() でアクティブ化
ここでは F11 によるフルスクリーンをユーザーに任せつつ、Selenium 側から maximize_window() を呼ばないように注意しています。maximize_window() を呼ぶと F11 フルスクリーンが解除されてしまうためです。
5-3. スクリーンショット取得ロジック
1ページごとのスクリーンショットは、PyAutoGUI を用いて行います。
- config.json に screenshot_region が設定されていなければ、フルスクリーンをキャプチャ
[x, y, width, height]が設定されている場合、その矩形をキャプチャ- 画像は output_dir(例: data)配下に、
page_0001.png,page_0002.png, … といった連番ファイル名で保存
エラーが発生した場合でも、ページ番号をログに残すようにし、どこまで進んだかが分かるようになっています。
5-4. ページ送りロジック(3段階のフォールバック)
ページ送りは、このツールの肝となる部分です。サイト側の JavaScript 実装やフォーカス状態などによって効かない操作もあるため、複数の方法を段階的に試すようにしています。
- 方法1: Selenium から send_keys
- body = driver.find_element(“tag name”, “body”)
- body.send_keys(arrow_key) を実行(arrow_key は page_turn_direction により ARROW_LEFT / ARROW_RIGHT が選択される)
- URL の変更有無を見るなどして成功・失敗の手がかりとする
- 方法2: JavaScript で
KeyboardEventを発火- execute_script を用いて、
keydownイベントを合成 key,code,keyCode,whichなどをArrowLeftorArrowRightに合わせて設定- ページ番号を示す要素があればログに出力
- execute_script を用いて、
- 方法3: PyAutoGUI によるフォールバック
- 画面中央付近をクリックして確実に Kindle ビューをフォーカス
- PyAutoGUI で pyautogui.press(‘left’ or ‘right’) を送信
- page_turn_direction に応じてキーを切り替え
この三段構えにより、Selenium 側の制限やサイト側のイベントハンドリングにもある程度耐性を持たせています。
6. PDF 生成と後処理
全ページのキャプチャが完了したら、次のフェーズは PDF 生成です。
- output_dir 内の
page_*.pngをページ番号順にソート - img2pdf.convert() に渡して1つの PDF バイト列に変換
- pdf_filename が
nullの場合は現在時刻から自動でファイル名を生成 - 生成された PDF ファイルをディスクに書き出し
delete_screenshotsがtrueの場合は、page_*.pngを削除してディスク容量を節約
img2pdf は元画像をそのまま PDF のページに埋め込むため、画質劣化がほとんどなく、高解像度のスクリーンショットであればそのまま高品質な PDF を得ることができます。一方で PDF ファイルサイズは大きくなりがちなので、必要に応じて外部ツールで圧縮する運用も想定しています。
7. テスト用ツールと検証方法
本番キャプチャの前に、ページ送りだけを検証するためのスクリプトとして test_page_navigation.py と test_navigation.bat を用意しています。
想定する使い方は次の通りです。
- Kindle Cloud Reader で本を開き、最初のページにして F11 フルスクリーン
- 別のターミナルから test_navigation.bat を実行
- 指定回数だけページ送りを試し、意図した方向に進むかどうかを確認
こうしたテスト専用スクリプトを分離しておくことで、本番処理前に安全に挙動を確認できるようになっています。
8. 運用上の注意点とベストプラクティス
8-1. 法的・倫理的な注意
- Amazon の利用規約および各国の著作権法を厳密に守ること
- このツールは「自分が購入している本を、自分のためにバックアップする」用途に限定すること
- 生成した PDF の再配布や共有は行わないこと
8-2. 実行前チェックリスト
運用時におすすめしているチェック項目は次の通りです。
- Chrome が最新版である
- ネットワークが安定している
- ディスクに十分な空き容量がある(ページ数 × 数MBを目安)
- config.json の total_pages が本のページ数と一致している
- page_turn_direction が本の挙動と合っている(手動で左右キーを試して事前確認)
- 実行中に他の作業をしなくてよいタイミングを選ぶ
8-3. 品質向上のヒント
- ブラウザは必ず F11 で全画面表示にし、ツールバーやタブバーを映り込ませない
- ズーム倍率は 100% を起点に、本のレイアウトが崩れない範囲で調整
- 動作が不安定な場合は page_delay を少しずつ伸ばして安定性を優先する
- 長時間・大量ページのキャプチャでは、いくつかのチャンクに分けて実行する
9. まとめ
本記事では、Kindle Cloud Reader 上の本を自動的にスクリーンショットして PDF にまとめる Python ツールの設計と実装について、以下の観点から詳しく解説しました。
- Selenium と PyAutoGUI を組み合わせたブラウザ操作とスクリーンショット取得
- 設定ファイル config.json による柔軟な制御(ページ数、遅延、領域、ページ方向など)
- Kindle Cloud Reader 独自の挙動(タブ切り替え、F11 フルスクリーン、ページ送り方向の違い)への対応
- ページ送りを3段階のフォールバックで実現する堅牢な実装
- img2pdf による高画質 PDF 生成と、その後処理
実装レベルの詳細を追いながらも、「なぜそう設計したのか」という背景も含めて紹介しましたので、同様の自動化ツールを開発する際の参考になるはずです。
今後の発展としては、ページ数の自動検出、目次情報の抽出、OCR によるテキスト化など、さらなる自動化や利便性向上の余地が多く残されています。
そうした改善を行う際にも、このツールの構造や設定ベースの設計は良いスタート地点になるでしょう。


コメント