2万件のkindleハイライトを横断検索する.1

# プロンプト編

pythonのpの字も知らないド初心者が、chatGPTと殴り合いながら、kindleハイライトをスクレイピングし、csvに保存し、横断検索とランダム表示機能を備えたビューアを作ることに成功したので、その過程を結果をここに残します。

最終的にはこのようなアプリケーションを完成させることが目標です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4066587/b2d1eece-d940-4d56-8d8d-df7469f9ef4f.png" width=50%>



## ■きっかけ

世の中にはすでにkindleハイライトをスクレイピングするサービスや拡張機能が存在します。私が知ってるだけで２つあります。

**Booknotion Z**：もともとiOS向けのアプリだったものが進化して、ハイライトを集めてweb上に保存したり、保存したものをnotionにエクスポートできるようになりました。しかし、web保存されたものはタイトル単位で管理されるので横断検索ができません。notionへのエクスポートは動作が不安定で、500冊20000件ほどあるハイライトのうち、数百件しかエクスポートできませんでした。

**obsidianの拡張機能**：obsidianというノートアプリに、コミュニティプラグインという有志が作成したプラグインを導入する機能があります。そのコミュニティプラグインに、kindle highlightsというものが存在します。しかし、動作が不安定で、数十冊読み込んで動作が停止しますし、最終更新日から数年経っていてアップデートされる気配がありません。

そういうわけで、どちらも使い勝手が悪く、どうしたもんかなあと思っていたところ、どこぞのクソガキどもがAIにプログラムを書かせて不正クレカを量産していた、というニュースを見てハッとしました。それなら私だってスクレイピングできんじゃね？


## ■前提

まずchat GPTにpythonのことをいろいろ聞きました。その上で、アプリケーション開発に必須と思われる必要最低限の知識を説明します。知ってるひとは飛ばしてください。
素人による浅い理解であることをどうかご容赦ください。

### ◎仮想環境とか
pythonは、PC内部に空き地を確保するようなイメージです。我々はその空き地に、遊具だらけの児童公園を作ったり、洗い場完備のドッグランを作ったりしたいのです。なにを作りたいかによって必要な材料も違います。材料はライブラリという名目でセットになっています。鉄骨ライブラリとか、水道ライブラリとか、塗料ライブラリとかそんな感じです。作りたいものに応じて、必要なライブラリを用意します。

児童公園を作りたいのに筋トレライブラリがあったら邪魔だし、ドッグランを作りたいのに病院ライブラリがあったら邪魔です。なので、必要なところに必要な材料だけが届くように、厳密に管理する必要があります。この厳密な管理を、プロのみなさんは「仮想環境を構築する」と言います。

実際には、pythonでアプリケーションを作る場合、親となるルートフォルダを1つ決めて、その中に必要なファイルを入れていきます。ルートフォルダ以下が仮想環境の範囲となり、仮想環境下でインストールしたライブラリは、そのルートフォルダ内でしか働きません。

つまり、アプリAのためにルートフォルダAを作って、ルートフォルダAの中に仮想環境を構築してSeleniumというライブラリをインストールしていたとしても、別のアプリBのためにルートフォルダBを新たに作った場合には、ルートフォルダBでもまた仮想環境を構築してSeleniumを再びインストールする作業が必要だということです。

仮想環境を構築せず、PC全域に有効になるようにライブラリをインストールすることもできるようですが（グローバルインストールって言うらしい）、どうもこれはプロのみなさんは好ましく思っていないようです。chatGPTにもダメだって言われました。

### ◎IDLEとか
pythonの編集には、pythonをインストールしたら一緒についているIDLEというものを使いました。これがなんなのか、今に至るまでよく分かっていません。コードを実行した結果やエラーが表示されるので、モニターみたいなもんだと思っています。

ややこしいのが、普通にIDLEを起動してコードを貼り付けたのでは、仮想環境のライブラリが適応されないということです。仮想環境のライブラリが適応されないということは、さきほどの例に戻ると、設計図（chatGPTが考えてくれたpythonのコード）はあるのに材料（ライブラリ）がねえ、ということです。

chatGPTに考えてもらったコードをただ動かすだけでも、仮想環境のライブラリを適応させるため、以下の手順を厳密に守る必要があります。

1. コマンドプロンプトを開く（最近はPowerShellとかいう上位互換のやつがあるらしいけど今回は使いませんでした）
2. コマンドプロンプトでルートフォルダに移動する
3. コマンドプロンプトで仮想環境を構築する（初回だけです）
4. コマンドプロンプトで仮想環境をONにする（プロはアクティベートと言います）
5. 仮想環境下にライブラリをインストールする（初回だけです）
6. コマンドプロンプトでIDLEを開く
7. IDLEで新規ファイルを開きコードを書く画面を開く
8. chatGPTに考えてもらったコードを貼り付けて動かす


おわかりの通り、コマンドプロンプトの操作が必須です。ですから、ズブのド素人である我々は、chatGPTにpythonのコードを考えてもらいつつ、コマンドプロンプトの操作も教えてもらう必要があります。
幸いにもコマンドプロンプトで必要な操作（入力しなければいけないコード）は限られており、さらにバッチファイルという仕組みを使うことで、コマンドプロンプトでコードを入力するのを省略することもできます。
IDLEを開こうとするたびに毎回、コマンドプロンプト開いて～ルートフォルダのパス入れて～とかやってたら気が狂うので、適宜バッチファイルで自動化しながら作業を進めます。

### ◎どこに作るか
ちなみに、chatGPTによれば、仮想環境のライブラリのインストールは相対パスではなく絶対パスで行われるらしく、ルートフォルダを移動したり名前を変えたりすると、せっかく構築した仮想環境がぶっ壊れるそうです。その場合には、改めて仮想環境を構築してライブラリの再インストールが必要です。

慣れれば大した手間でもないですが、最初のうちはライブラリの再インストールなんて考えただけで泣いちゃうと思うので、ルートフォルダをどこに置くかはよく考えましょう。アプリケーション起動のトリガーとなるファイル（一番最後に作成予定）は、ルートフォルダとは別の場所、例えばデスクトップ等に自由に置けるので、ルートフォルダは邪魔にならない場所にするのがいいと思います。マイドキュメントの奥深くとか。

## ■chatGPTのプロンプト

python本体のインストールのみ終えた状態で、chatGPTと語り合うことにしました。今回の件で、私が一番最初に投げかけたプロンプトは以下のとおりです。

```
プログラムを書いてもらうためのプロンプトを作りたいです。
私の要望は大抵はじめのうち曖昧で抽象的だから、
会話しながらプランを具体的にしていきたいと思っています。
まず概要を固めてから、実際の手順について検討したほうがいいと思って、
こんなプロンプトを考えてみました。
これを叩き台にして改善点を教えてください。

 @@@@@@@@@@@@@@@@@@@@@ 
あなたは優秀で気の利くプログラマーです。 私はプログラムの初心者です。
あなたは私の要望を叶えるプラグラムを以下の手順に従って考えてください。

###手順 
1.まず、あなたは私に、どんなことをしたいのか質問します。
  この質問に対する私の回答は『当初の要望』と名付けます。 
2.あなたは私の回答を受け、不明点や確認しておきたいポイントをさらに私に質問してください。
  ここでの狙いは、あなたとの対話を通じて私の『当初の要望』を、
  より具体的で意味のあるものに改善することです。 
3.あなたは、私との対話を通じて十分に情報を得て分析が完了したと判断したら、
 『当初の要望』に分析結果を加えて整理してください。これを『本当の要望』と名付けます。 
4.私が、あなたの提案した『本当の要望』に納得したら、
 『本当の要望』を実現するためのステップについて概要を教えてください。 
5.私がその概要に納得したら，そこではじめて詳細な手順や必要な下準備について教えてください。 
6.私が了承したら、手順1から順番に、私の進捗に合わせて少しずつ具体的な指示を出してください。
  指示を出す時は常に、いま行っている作業が全体の中でどの位置にあるのか、確認した上で私に提示してください。 

###私の開発環境 
windows11 
Python
 @@@@@@@@@@@@@@@@@@@@@

```



プロンプトを考えてもらうためのプロンプトです。モノの本によれば、プロンプトは以下のことに気をつけるといいらしいです。
1. 自分とAIに役割をあたえる
2. マークダウン形式を使う
3. 回答の手本を見せる

ちなみにマークダウン形式はよくわかりません。
何往復かの対話の結果、chatGPTは以下のような最終プロンプトを作成しました。

```
# あなたの役割 
- **あなた（AI）** は優秀で気の利くプログラマー兼メンターです。
- **私（ユーザー）** はプログラミング初心者です。専門用語は必ず分かりやすく解説してください。 


# 開発フロー 
1. **要望ヒアリングフェーズ**
- 私に「どんなことをしたいか」を質問してください。 
- 私の回答は **《当初の要望》** と呼びます。 

2. **深掘り・明確化フェーズ** 
- 《当初の要望》をもとに不明点や確認したいポイントを**複数回に分けて**質問し、
  《当初の要望》を具体化します。 
- 必要に応じてサンプル入力・出力例、画面イメージ、制約条件を尋ねてください。 

3. **合意形成フェーズ** 
- 十分に情報を得たら、整理・分析した内容を **《本当の要望》** として提示してください。 
- 私が **「OK」** と返信したら合意成立です。NG の場合は再度質問してください。 

4. **概要設計フェーズ** 
- 《本当の要望》を満たすための**全体ステップ**を箇条書きで提示してください。 
- 私が **「OK」** と返信したら次へ進んでください。 

5. **詳細設計フェーズ** 
- ステップごとの詳細手順・必要な下準備・想定されるコマンド例を提示してください。 
- 私が **「OK」** と返信したら実装フェーズへ。 

6. **実装サポートフェーズ** 
- ステップ 1 から順に、進捗に合わせて**小さなタスク単位**で具体的な指示を出してください。 
- 各タスク開始時に「全体の中での位置づけ」を示してください（例: 全6ステップ中の 2/6）。 
- エラーが出たらログを貼るので、原因調査と解決策を提案してください。 

7. **完了判定** 
- 以下を満たしたら完了とします。 
1. 動作確認用のサンプルが期待通りに実行できる 
2. コードにコメントまたは簡潔な README が付く 
3. 私が **「完了」** と返信する 

# 開発環境 
- OS: Windows 11 
- Python: 3.13.x（仮想環境は venv 予定） 
- エディタ: IDLE (標準付属) 
- 実行方法: IDLE で Run Module (F5) 

# 出力フォーマットの希望 
- 長い説明には見出し (##) と番号付きリストを使用 
- 必要に応じて図や表を提案 

# 注意点 
- 専門用語は初出時に簡潔な説明をつけてください。 
- 要望変更や追加があれば随時相談し、合意のうえで《本当の要望》を更新してください。 
```

このプロンプトで重要なことは、《当初の要望》を深堀りして《本当の要望》を確認し、その上ではじめて具体的な開発に進む、ということです。必ず、私とchatGPTとで明確なゴールを共有し、その後に詳細開発に進みます。この約束を取り決めておかないとAIは勝手にぺらぺら喋り始めるので、どんなアプリケーションがいいか悩んでいる段階でいきなりコードを提出してきます。

また、どんなプロンプトにするか固まったあとは、新しいチャットの画面に切り替えて最終プロンプトを使用してください。AIは長く話していると記憶が混濁してくるので、混乱を防ぐ目的があります。

AIと私とで共有した明確なゴールに《本当の要望》とわざわざ名前を付けているのも、AIの記憶混濁を防ぐためです。開発中、細かな質問を続けているうちに、AIは最終的なゴールを忘れて「よし！ウィンドウのレイアウトが決まったね！これで完成！」とか言い始めるので、「違うよ、これは単にウィンドウのレイアウトが決まっただけだよ。私たちが一緒に考えた《本当の要望》を思い出してください」などと軌道修正するために使用します。

この最終プロンプトを投げかけたあと、何度かやりとりを繰り返し、基本機能として以下の内容を確認しました。

```
私はpythonを使ってkindleのハイライト情報をスクレイピングして、
ハイライト情報をまとめたcsvファイルを作成しました。 
このcsvファイルには、およそ500冊分・2万件のハイライト情報が含まれています。
これを使用して、簡単なデスクトップアプリを作りたいと思っています。 
私が作成したcsvファイルをアップロードするので、内容を確認してください。 

作成するデスクトップアプリには以下の３つの機能を必須で備えたいです。 

1. 検索機能 指定したワードを含むハイライトを検索して表示させたいです。 
   横断的に検索したいので、検索範囲はハイライト本文だけでなく
   タイトルと著者名を含みたいです。 
   
2. ランダム表示機能 過去のハイライトに偶発的に触れる機会を得たいので、
   ボタンを押下するたびに表示が切り替わるような、
   ランダムピックアップ機能を持たせたいです。 

3. データベースファイルの指定 ハイライト情報を含むcsvファイルを、
   不定期に新しいものに差し替えたいと考えています。
   というのも、ハイライトは新しい本を読み終わるたびにどんどん増えていきますが、
   増えたハイライトの差分だけを取得して元のcsvファイルに付け加えることは、
   ファイルの破損の可能性もあってあまり現実的ではないと思うからです。
   ですから、データベースの元になるcsvファイルをコード中で指定するのではなく、
   アプリケーション上で手動で指定できればいいと思いました。
```

厳密に言うと、この時点ではスクレイピングの完全な成功には至っていなかったのですが、さっさと話を進めたかったのでスクレイピングに成功したことにしました。

このあと更にやりとりを重ね、《本当の要望》の詳細な部分が固まります。
chatGPTにまとめてもらったのが、このような内容です。

```
以下がこれまでの整理を踏まえた《本当の要望》です。

《本当の要望》
Python（Tkinter）で動作する、Windows 11 向けのデスクトップアプリとして、
以下の機能・仕様をすべて備えること。

CSV ファイル読み込み／切り替え
ユーザーが任意の CSV（“タイトル／著者名／ハイライト本文” の３列、ヘッダーなし）をアプリ上で選択できる。
選択したファイルを即座に読み込み、以降の機能で使う。


タブベースの画面構成 (ttk.Notebook)
タブ①：ランダム表示
「次を表示」ボタン押下で、読み込んだ CSV からランダムに１件を抽出。
抽出データは Text ウィジェット内で、
見出し行：【番号】タイトル — 著者名 を太字、大きめフォントで表示
本文行：ハイライト本文を改行区切りで表示

タブ②：検索機能
テキスト入力欄（Entry）にキーワードを入力し、「検索」ボタンを押下。
キーワードは「タイトル」「著者名」「ハイライト本文」の横断検索対象。
結果は Text ウィジェットに一覧表示（見出し＋本文形式）。
検索ワードは黄色背景などで強調表示。

タブ③：ファイル指定
「ファイルを開く」ダイアログで CSV を選択。
現在選択中のファイルパスを画面にテキスト表示。


モダン UI・高解像度対応
高 DPI 対応：ctypes.windll.shcore.SetProcessDpiAwareness(1) を呼び出し、画面にじみを防止。
フォント指定：日本語フォント（Meiryo／Yu Gothic など）を tkinter.font.Font で明示的に設定。
テーマ：ttk.Style().theme_use("vista")（または環境に応じて "xpnative"/"clam"）を適用し、
ネイティブ風見た目に。

快適なスクロール操作
マウスホイール <MouseWheel> をキャッチし、１ノッチあたり約３行分スクロールするロジックを実装。
```

ここに至るまでのやりとりの途中で、アプリケーションのウィンドウはどんな構成・どんなデザインがいいか？という話になったので、サンプルコードを書いてもらって実際にpythonでウィンドウを表示させて、chatGPTがどんなものを作ろうとしているのか確認しました。

サンプルを見て「解像度が低すぎる！」「それじゃ今風の表示にしましょか～」とか「検索結果はライン表示じゃなくてテキストボックスに表示させるのがわかりやすいかも？」「テキストボックスならキーワードハイライトも付けれますわ」「よろしく～」とか「スクロール速度が遅いんだけどなんですのこれ」「実はスクロール速度って制御できるんスよね」「まじか」などの会話があり、その結果を反映して《本当の要望》が出来上がっています。

chatGPTが作ってくれたサンプルはこんな感じでした。まじでwindows95かと思った。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4066587/62d69948-8f91-41b4-92ab-490c334e76f5.png" width=50%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4066587/98d45803-d9bd-4e69-a80b-5ad8f2caeba7.png" width=50%>



ここまで詳細を詰められれば、あとはchatGPTに全力でコードを書いてもらい、エラーを潰し、追加で思いついた機能を入れてもらい、ウィンドウのレイアウトを調整して、完成に向けて頑張るだけです。

コードを書いている途中で、コマンドプロンプトの操作がわかんないとか、GUIライブラリって他になにがあるんだろうとか、重要度の低い疑問が出てくる場合があります。そのときは、別のチャット画面を開いてそちらで質問するようにしてください。AIの記憶混濁を防ぐために、開発チャットは開発の本筋に集中したほうがいいです。

エラーの対応や機能の追加などで、部分的にコードを修正することが何度もあるのですが、たまにコード全部をまとめて貼ったり、pythonファイルそのものをアップロードしたりして、間違いがないか適宜確認してもらいましょう。なにせ自分で読めないものを作っているので、独力では全然間違いに気がつけません。それに、「コード全体を見返してみたらもっといい書き方あったわ」などとchatGPTが修正案を出してくれることもあります。

次回、スクレイピング編に続きます。