You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写脚本批量导入Obsidian Markdown至Wiki.js并实现双向同步

实现Obsidian笔记批量导入Wiki.js及双向同步的通用步骤

一、前期准备

  • 启用Wiki.js API:在后台「设置-API」中开启API访问,生成并妥善保存API密钥
  • 整理Obsidian文件:将需导入的MD笔记和图片统一放到一个目录,确保图片使用相对路径(Obsidian默认是相对路径,若不是需批量替换)
  • 安装基础工具:
    • 安装Python 3.8及以上版本
    • 通过pip安装依赖:pip install requests python-frontmatter watchdog

二、批量导入(含本地图片)

1. 批量上传图片到Wiki.js媒体库

编写可直接修改使用的脚本片段:

import requests
import os
import json

# 替换为你的实际配置
WIKIJS_API_BASE = "你的Wiki.js域名/api/v1"
API_KEY = "你的API密钥"
IMAGE_SOURCE_DIR = "Obsidian笔记的图片目录绝对路径"

headers = {"Authorization": f"Bearer {API_KEY}"}
# 存储本地路径到Wiki.js图片URL的映射
local_to_wiki_url = {}

for file_name in os.listdir(IMAGE_SOURCE_DIR):
    if file_name.lower().endswith((".png", ".jpg", ".jpeg", ".gif", ".webp")):
        file_path = os.path.join(IMAGE_SOURCE_DIR, file_name)
        with open(file_path, "rb") as img_file:
            upload_data = {"file": img_file}
            resp = requests.post(f"{WIKIJS_API_BASE}/media/upload", headers=headers, files=upload_data)
            if resp.status_code == 200:
                wiki_url = resp.json()["data"]["url"]
                # 按Obsidian里的相对路径存储映射,比如 "./images/xxx.png"
                local_rel_path = os.path.join("./images", file_name)
                local_to_wiki_url[local_rel_path] = wiki_url
                print(f"上传成功:{file_name} -> {wiki_url}")

# 把映射保存到文件,后续替换MD路径用
with open("image_map.json", "w") as f:
    json.dump(local_to_wiki_url, f)

运行脚本后,所有图片会上传到Wiki.js,同时生成image_map.json记录路径映射。

2. 替换MD图片路径并批量导入笔记

编写导入脚本:

import requests
import os
import frontmatter
import json

# 替换为你的实际配置
WIKIJS_API_BASE = "你的Wiki.js域名/api/v1"
API_KEY = "你的API密钥"
MD_SOURCE_DIR = "Obsidian笔记目录绝对路径"

headers = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
# 读取之前生成的图片路径映射
with open("image_map.json", "r") as f:
    local_to_wiki_url = json.load(f)

# 存储MD文件名到Wiki.js页面ID的映射,用于后续同步
page_map = {}

for file_name in os.listdir(MD_SOURCE_DIR):
    if file_name.endswith(".md"):
        file_path = os.path.join(MD_SOURCE_DIR, file_name)
        # 读取MD元数据和内容
        note = frontmatter.load(file_path)
        # 替换图片路径
        updated_content = note.content
        for local_path, wiki_url in local_to_wiki_url.items():
            updated_content = updated_content.replace(local_path, wiki_url)
        # 构建上传参数
        payload = {
            "title": note.get("title", file_name[:-3]),  # 优先用Obsidian标题元数据,否则用文件名
            "content": updated_content,
            "isPublished": True,
            "locale": "zh-CN"
        }
        # 创建Wiki.js页面
        resp = requests.post(f"{WIKIJS_API_BASE}/pages", headers=headers, json=payload)
        if resp.status_code == 200:
            page_id = resp.json()["data"]["id"]
            page_map[file_name] = page_id
            print(f"导入成功:{file_name} -> 页面ID {page_id}")

# 保存页面映射,用于后续同步
with open("page_map.json", "w") as f:
    json.dump(page_map, f)

运行脚本完成所有笔记的批量导入。

三、双向同步实现思路(低代码版)

1. Obsidian → Wiki.js 自动同步

  • 利用watchdog库监听Obsidian目录的文件变化(新增、修改、删除)
  • 触发逻辑:
    • 新增/修改图片:自动上传到Wiki.js,更新image_map.json
    • 新增/修改MD文件:替换图片路径后,若为新文件则创建Wiki.js页面,若为已导入文件则通过页面ID调用API更新内容
    • 删除文件:通过页面ID调用API删除对应Wiki.js页面

2. Wiki.js → Obsidian 自动同步

  • 启用Wiki.js Webhook:在后台「设置-Webhooks」添加钩子,当页面修改/删除时,发送POST请求到本地服务
  • 编写简单本地HTTP服务(用Flask):
    • 接收Webhook的页面修改数据,下载页面MD内容
    • 替换Wiki.js图片URL为本地路径(借助image_map.json反向映射)
    • 将修改后的内容保存到Obsidian对应目录
    • 若收到删除通知,删除Obsidian中对应MD文件

3. 冲突处理规则

  • 设定修改优先级:比如优先保留Obsidian的修改,或优先保留Wiki.js的修改
  • 记录每个文件的最后修改时间,同步时仅更新目标端中版本更旧的内容

四、无代码简化方案

  • 批量导入:手动将图片上传到Wiki.js媒体库,批量替换MD中的本地路径后,使用Wiki.js后台「内容-导入」功能上传MD文件
  • 双向同步:将Obsidian目录和Wiki.js页面内容同步到同一个Git仓库,通过Git的版本控制来处理同步和冲突

内容的提问来源于stack exchange,提问作者Ring

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 13:04:55