WordPressで書いた記事をObsidianでも管理したい──
そんなことを考えたことはありませんか?
私は以前、Obsidian Web Clipperを使って、公開した記事を1つずつMarkdown化して取り込んでいました。
しかし、この作業は思った以上に手間がかかり、「毎回やるのは正直面倒…」というのが本音でした。
そこで、PythonスクリプトでWordPressの記事を自動的にObsidianへ取り込む仕組みを作ってみました。
今回は、その背景と具体的な実装手順を紹介します。
WordPress × Obsidian をつなぐ目的
ObsidianはMarkdown形式で情報を整理できる強力なノートツールです。
ブログの下書きやネタ管理だけでなく、公開した記事をナレッジとして再活用するのにも最適です。
私の場合、Obsidian側で Smart Composer プラグイン を使い、既存の記事を再構成したり、過去の文章を次の記事ネタとして再利用しています。
そのため、「WordPressで公開した記事をObsidianのVault内にMarkdownで残す」ことが重要でした。
でも、記事を公開、更新するたびに手作業でクリップするのは続けられない──
なんとかラクできないかなと調べて、WordPress REST API と Pythonで自動化する仕組みを構築しました。
仕組みの概要
今回はPythonのスクリプトを使って、WordPress REST APIから公開記事と固定ページを取得し、MarkdownでObsidianのVaultに保存する仕組みを構築しました。
記事を公開・更新するタイミングでスクリプトを実行してVaultに保存します。
▶ フロー概要
- WordPress REST APIから記事を取得
- requestsでデータを取得し、markdownifyモジュールでMarkdown化
- YAMLヘッダーを付加
- iCloud Drive上の My Vault/PublicBlog/ に保存
- Obsidianからアクセスできる状態に
環境と前提条件
今回の環境、前提条件は以下のとおりです。
この環境で動作を確認して、その後他のOSなどでも検証していきたいと思います。
PythonはMacOSに標準でインストールされているものを利用します。
markdownifyはHTMLをMarkdown形式に変換するPythonのライブラリです。
以下のコマンドでインストールしておきます。
pip install requests markdownify python-dateutil
WordPressの記事をMarkdown化してObsidianに同期する
このスクリプトは、WordPressのREST APIから記事(投稿+固定ページ)を取得し、本文をMarkdown化してObsidian VaultのPublicBlogフォルダにあるドメイン名フォルダに自動保存します。
投稿は posts/ フォルダ、固定ページは pages/ フォルダにそれぞれ分けて出力されます。

▶ スクリプト
スクリプトは作成後、ObsidianのVaultのPublicBlogフォルダに、ファイル名wp_to_obsidian.pyで保存してください。
「設定(あなたの環境に合わせて変更)」の部分は環境に合わせて変更します。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
WordPress → Obsidian Markdown Exporter(投稿+固定ページ分離版)
------------------------------------------------
WordPressの公開投稿と固定ページを取得し、
Markdown(.md)に変換して iCloud Drive 上の Obsidian Vault に保存します。
出力構成:
~/Library/Mobile Documents/iCloud~md~obsidian/Documents/My Vault/PublicBlog/<ドメイン名>/
├── posts/
└── pages/
"""
import os
import re
import sys
import requests
from markdownify import markdownify as md
from urllib.parse import urljoin
from dateutil import parser as dp
# ---------------------------------------------------
# 🔧 設定(あなたの環境に合わせて変更)
# ---------------------------------------------------
SITE = "https://hirosfreedomblog.com" # あなたのWordPressサイトURL
SINCE = "2024-01-01" # この日付以降の記事を取得
OUT_BASE = "/Users/myaccount/Library/Mobile Documents/iCloud~md~obsidian/Documents/My Vault/PublicBlog"
# ---------------------------------------------------
def html_to_md(html: str) -> str:
"""WordPressのHTML本文をMarkdownに変換"""
html = re.sub(r"<!--.*?-->", "", html) # 不要なブロックコメント削除
text = md(html, heading_style="ATX", bullets="*") # Markdown化
return re.sub(r"\n{3,}", "\n\n", text).strip() + "\n"
def fetch_posts(endpoint: str, params: dict):
"""WordPress REST APIから記事を取得"""
try:
resp = requests.get(urljoin(SITE, endpoint), params=params, timeout=20)
resp.raise_for_status()
return resp.json()
except Exception as e:
print(f"❌ {endpoint} の取得に失敗: {e}")
return []
def save_post(item: dict, out_dir: str):
"""1件の記事をMarkdownとして保存"""
title = re.sub("<[^<]+?>", "", item["title"]["rendered"]).strip()
date = dp.parse(item["date"]).date().isoformat()
slug = item["slug"]
url = item["link"]
md_text = html_to_md(item["content"]["rendered"])
os.makedirs(out_dir, exist_ok=True)
fname = f"{date}-{slug}.md"
fpath = os.path.join(out_dir, fname)
with open(fpath, "w", encoding="utf-8") as f:
f.write(f"---\n")
f.write(f"title: {title}\n")
f.write(f"url: {url}\n")
f.write(f"published: {date}\n")
f.write(f"site: {SITE}\n")
f.write(f"---\n\n")
f.write(f"# {title}\n\n{md_text}")
print(f"✅ {fname} を保存 ({out_dir.split('/')[-1]})")
def main():
print("🔄 WordPress → Obsidian Export 開始")
domain = SITE.replace("https://", "").replace("http://", "").strip("/")
OUT_DIR = os.path.join(OUT_BASE, domain)
POSTS_DIR = os.path.join(OUT_DIR, "posts")
PAGES_DIR = os.path.join(OUT_DIR, "pages")
print(f"📁 出力先: {OUT_DIR}")
os.makedirs(POSTS_DIR, exist_ok=True)
os.makedirs(PAGES_DIR, exist_ok=True)
params = {
"status": "publish",
"per_page": 50,
"after": f"{SINCE}T00:00:00",
"_fields": "date,slug,title,content,link",
}
# 投稿と固定ページをそれぞれ取得
posts = fetch_posts("/wp-json/wp/v2/posts", params)
pages = fetch_posts("/wp-json/wp/v2/pages", params)
if not posts and not pages:
print("⚠️ 新しい投稿や固定ページは見つかりません。")
return
for p in posts:
save_post(p, POSTS_DIR)
for p in pages:
save_post(p, PAGES_DIR)
total = len(posts) + len(pages)
print(f"🎉 Export 完了!合計 {total} 件(投稿 {len(posts)}/固定ページ {len(pages)})を出力。")
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print("\n⏹ 中断しました。")
except Exception as e:
print("❌ 予期せぬエラー:", e)
sys.exit(1)
コードのポイントは以下のとおりです。
| 目的 | コード部分 | 解説 |
|---|---|---|
| WordPress APIを呼び出す | fetch_posts() | /posts と /pages の2種類を取得 |
| HTMLをMarkdownに変換 | html_to_md() | markdownify ライブラリを使用 |
| メタ情報を保持 | YAMLブロック | タイトル・URL・公開日などをObsidianで使える形に保存 |
| 出力先を分離 | posts/ pages/ | 記事と固定ページを別フォルダ管理 |
| 上書き処理 | with open(…, “w”) | 更新時は既存ファイルを上書き(常に最新化) |
※ このスクリプトは毎回すべての記事を再取得・上書き保存するシンプルな仕組みです。記事数が多い場合は処理に少し時間がかかりますが、常に最新の状態を確実に反映できます。WordPressの記事数が非常に多い場合は、変更のあった記事のみ同期する「差分更新」方式に改良することも可能です。運用規模に応じて調整してください。
▶ 実行コマンド
初回実行で posts/ と pages/ フォルダが自動作成され、WordPressの記事がすべてMarkdownで保存されます。
python3 ~/Library/Mobile\ Documents/iCloud~md~obsidian/Documents/My\ Vault/PublicBlog/wp_to_obsidian.py
▶ 実行結果の例
🔄 WordPress → Obsidian Export 開始
📁 出力先: /Users/myaccount/.../PublicBlog/hirosfreedomblog.com
✅ 2025-10-25-shottr-mac-screenshot.md を保存 (posts)
・・・ 固定ページ、投稿ページの保存が表示されます。
・・・
・・・
🎉 Export 完了!合計 8 件(投稿 7/固定ページ 1)を出力。
▶ 出力構成(Finder / Obsidianで確認)
My Vault/
└── PublicBlog/
└── hirosfreedomblog.com/
├── posts/
│ ├── 2025-10-25-shottr-mac-screenshot.md
│ ├── 2025-10-24-obsidian-daily-note-todo.md
│ └── ...
└── pages/
├── about.md
├── privacy-policy.md
└── contact.md
WordPressの記事と固定ページが自動でObsidian Vaultに同期されています。
運用の工夫
無事に取り込めたので、Obsidianで以下の運用が可能になります。
- 記事更新後にコマンドを再実行 → 自動上書き
- iCloud同期で他のMac・iPadにも即反映
- Dataviewで記事一覧を自動生成
- Smart Composerで再構成・要約・再執筆
今後の展開アイデア
今回はWordPressの記事とObsidianを同期させる基本的な部分を実現しました。
今後は以下のような展開を考えています。
更新したらまた共有します。
まとめ
WordPress × Python × Obsidian の組み合わせで、「ブログの公開」と「知識管理」をシームレスに繋げることができました。
Markdownで記事を残しておけば、後から修正・引用・再構成が自在です。
手動では続かないことを自動化する──
それが、この仕組みを作った最大の目的です。
今後も機能を拡張しながら、より便利に使える形を模索していきます。
改善アイデアなどがあれば、ぜひ教えてください。
※ 注意: このスクリプトは自分が管理するWordPressサイトのバックアップや編集効率化を目的としたものです。第三者のサイトを無断で取得・保存することは著作権や利用規約に抵触する場合があります。

コメント