iPhoneのジャーナルを日記として利用していたのですがなぜかMacでは使えないのでエクスポートして別のツールを使うことにしました。
エクスポート
エクスポートの手順は下のとおりです。
(iOS18.4.1で確認しました。)
iPhoneの設定アプリを開きます。
一番下のアプリを選択します。
「ジャーナル」を選択します。(さ行にありました)
「すべてのジャーナルエントリーを書き出す」を選択します。
「iPhoneのパスコードを入力」と出るのでパスコードを入力します。
「書き出しますか?」と出るので「書き出す」を選択します。
「書き出し中」と出るので少し待ちます。
保存先を選択します。(iCloud Driveのルートにしました。)
保存を押します。
AppleJournalEntries.zipとして保存されます。
展開後の内容
ファイルを展開するとindex.htmlとEntriesフォルダとResourcesフォルダになります。
Entriesに本文がHTML形式で保存されています。
index.htmlが目次になるのでそのままでも利用できます。(ただしResourcesにある画像ファイルがHEIC形式なのでブラウザで開いても見えません。)
マークダウンに変換
Obsidianで使いたいので各ファイルをマークダウンに変換します。
Pythonを使いました。
使う場合は
base_folder_path_input = “/xxxxx/AppleJournalEntries”
の部分をZIPを展開したフォルダに書き換えてください。
import os
import re
from bs4 import BeautifulSoup
import urllib.parse
def convert_html_to_markdown_text(html_content):
"""
HTMLコンテンツから画像タグとその他のHTMLタグを除去し、テキストを抽出する。
"""
soup = BeautifulSoup(html_content, "html.parser")
for img_tag in soup.find_all("img"):
img_tag.decompose()
text = soup.get_text(separator="\n", strip=True)
text = re.sub(r"\n\s*\n", "\n\n", text)
return text
def process_html_files_in_folder_simple(source_folder_path, output_folder_full_path):
"""
指定されたフォルダ内のHTMLファイルを処理し、指定された出力フォルダにMarkdown形式で保存する。
エラーハンドリングや重複チェックは簡略化されている。
- yyyy-mm-dd_文字列.html -> yyyy-mm-dd_文字列.md
- yyyy-mm-dd.html -> yyyy-mm-dd.md
重複するファイル名は上書きされる。
"""
os.makedirs(output_folder_full_path, exist_ok=True)
print(f"出力先フォルダ: '{output_folder_full_path}'")
print(f"'{source_folder_path}' 内のHTMLファイルを処理しています...")
processed_files_count = 0
for encoded_filename in os.listdir(source_folder_path):
filename = urllib.parse.unquote(encoded_filename)
if filename.lower().endswith(".html"):
match = re.match(
r"(\d{4}-\d{2}-\d{2})(?:_(.+))?\.html$", filename, re.IGNORECASE
)
if match:
date_part = match.group(1)
string_part_content = match.group(2)
if string_part_content:
base_md_name_without_ext = f"{date_part}_{string_part_content}"
else:
base_md_name_without_ext = date_part
md_filename = base_md_name_without_ext + ".md"
md_filepath = os.path.join(output_folder_full_path, md_filename)
html_filepath = os.path.join(source_folder_path, encoded_filename)
with open(html_filepath, "r", encoding="utf-8") as f_html:
html_content = f_html.read()
markdown_text = convert_html_to_markdown_text(html_content)
with open(md_filepath, "w", encoding="utf-8") as f_md:
f_md.write(markdown_text)
print(f"変換完了: '{filename}' -> '{md_filename}'")
processed_files_count += 1
else:
pass
print(f"\n処理完了。 {processed_files_count} ファイルを変換しました。")
print(f"変換されたファイルは '{output_folder_full_path}' に保存されています。")
if __name__ == "__main__":
# ユーザーが指定したベースフォルダパス
base_folder_path_input = "/xxxxx/AppleJournalEntries"
base_folder_path = os.path.expanduser(base_folder_path_input)
input_entries_folder = os.path.join(base_folder_path, "Entries")
output_markdown_folder = os.path.join(base_folder_path, "converted_markdown_files")
process_html_files_in_folder_simple(input_entries_folder, output_markdown_folder)
import re
from bs4 import BeautifulSoup
import urllib.parse
def convert_html_to_markdown_text(html_content):
"""
HTMLコンテンツから画像タグとその他のHTMLタグを除去し、テキストを抽出する。
"""
soup = BeautifulSoup(html_content, "html.parser")
for img_tag in soup.find_all("img"):
img_tag.decompose()
text = soup.get_text(separator="\n", strip=True)
text = re.sub(r"\n\s*\n", "\n\n", text)
return text
def process_html_files_in_folder_simple(source_folder_path, output_folder_full_path):
"""
指定されたフォルダ内のHTMLファイルを処理し、指定された出力フォルダにMarkdown形式で保存する。
エラーハンドリングや重複チェックは簡略化されている。
- yyyy-mm-dd_文字列.html -> yyyy-mm-dd_文字列.md
- yyyy-mm-dd.html -> yyyy-mm-dd.md
重複するファイル名は上書きされる。
"""
os.makedirs(output_folder_full_path, exist_ok=True)
print(f"出力先フォルダ: '{output_folder_full_path}'")
print(f"'{source_folder_path}' 内のHTMLファイルを処理しています...")
processed_files_count = 0
for encoded_filename in os.listdir(source_folder_path):
filename = urllib.parse.unquote(encoded_filename)
if filename.lower().endswith(".html"):
match = re.match(
r"(\d{4}-\d{2}-\d{2})(?:_(.+))?\.html$", filename, re.IGNORECASE
)
if match:
date_part = match.group(1)
string_part_content = match.group(2)
if string_part_content:
base_md_name_without_ext = f"{date_part}_{string_part_content}"
else:
base_md_name_without_ext = date_part
md_filename = base_md_name_without_ext + ".md"
md_filepath = os.path.join(output_folder_full_path, md_filename)
html_filepath = os.path.join(source_folder_path, encoded_filename)
with open(html_filepath, "r", encoding="utf-8") as f_html:
html_content = f_html.read()
markdown_text = convert_html_to_markdown_text(html_content)
with open(md_filepath, "w", encoding="utf-8") as f_md:
f_md.write(markdown_text)
print(f"変換完了: '{filename}' -> '{md_filename}'")
processed_files_count += 1
else:
pass
print(f"\n処理完了。 {processed_files_count} ファイルを変換しました。")
print(f"変換されたファイルは '{output_folder_full_path}' に保存されています。")
if __name__ == "__main__":
# ユーザーが指定したベースフォルダパス
base_folder_path_input = "/xxxxx/AppleJournalEntries"
base_folder_path = os.path.expanduser(base_folder_path_input)
input_entries_folder = os.path.join(base_folder_path, "Entries")
output_markdown_folder = os.path.join(base_folder_path, "converted_markdown_files")
process_html_files_in_folder_simple(input_entries_folder, output_markdown_folder)
コメント