ConfluenceページをMarkdownに変換する方法
PythonでConfluenceのページをMarkdownに変換する方法を紹介します。
モチベーション
なぜMarkdownに変換したいかというと、社内wikiとして利用しているConfluenceの既存ページを、生成AIのRAGから参照させるのが目的です。
PDFに変換する方法もありますが、PDFにすると元ページの構造や文章が崩れてしまい、RAGの精度が大きく低下してしまいます。一方、Markdownであれば元の情報を維持したままRAGのインプットとして利用できるため、精度向上が期待できます。また、PDFに比べてデータサイズを節約することもできます。
Markdownに変換する方法は?
Cloud版のConfluenceであれば、Markdown変換用の有料プラグイン(Markdown Exporter for Confluence | Atlassian Marketplace)も存在するようです。ですが、私の会社ではオンプレ環境のため独自に変換する方法を検討する必要があります。そこで今回、Pythonスクリプトによる変換を試してみました。
実行環境
Mac
Google Chrome
Python 3.11.x
load_dotenv
selenium
chromedriver-binary → バージョンはChromeに合わせる
beautifulsoup4
markdownify
処理の概要
Confluenceページにアクセス: Selenium(ただし、2要素認証が必要な場合は一部手動入力あり)
HTMLソース取得: Selenium
HTMLのパース: Beautiful Soup
Markdownへの変換: markdownify
ファイル出力
手順
ここでは、ページアクセス時に「アカウント/パスワード入力」 + 「2要素認証」が必要な環境を想定しています。
事前準備
# 以下の内容で.envファイルに環境情報をセットしておく
$ cat .env
ID=xxxx
PASSWORD=xxxx
Confluenceページへアクセス
SeleniumのChromeドライバ設定
import json
import chromedriver_binary
from selenium import webdriver
from selenium.webdriver.support.wait import WebdriverWait
driver = webdriver.Chrome()
# DOM要素が見つかるまでの待機時間(2要素認証を挟むため長めに設定)
driver.implicity_wait(30)
サインイン用のファンクションを定義
import os
from selenium.webdriver.common.by import By
def sign_in_to_confluence() -> None:
try:
id = os.environ.get("ID")
password = os.environ.get("PASSWORD")
# 以下、サインインページの環境に合わせて必要な画面操作をSeleniumで記述する
# 2要素認証が必要な場合は途中で手動認証を挟む
# driver.find_element(xxxx) ...
except Exception:
raise Exception("Confluecne sign in error.")
ページにアクセスする
from dotenv import load_dotenv
# 環境変数の読み込み
load_dotenv()
# URLを開く
url = "https://xxxxxx"
driver.get(url)
# サインイン
sign_in_to_confluence()
# ページタイトル取得
title = driver.title
HTMLソースの取得
JSレンダリング前のHTMLソースを利用したほうが正しくMarkdownに変換できるため、driver.page_source は使わずに「ページのソースを表示」からHTMLを取得します。
driver.get(f"view-source:{url}")
html_source = driver.find_element(By.TAG_NAME, "body").text
driver.close()
HTMLのパース
from bs4 import BeautifulSoup
# Confluenceのページコンテンツは"id=main-content"の要素に格納されている
soup = BeautifulSoup(html_source)
main_content = soup.find("div", id="main-content")
Markdownに変換する
from markdownify import markdownify as md
markdown = md(str(main_content), heading_style="ATX")
ファイル出力
import re
# 連続した空行を除外してからファイル出力
lines = str(markdown).split("\n")
stripped_lines = [line if line.strip() != "" else "" for line in lines]
joined = "\n".join(stripped_lines)
output = re.sub("\n{3,}", "\n\n", joined)
with open(f"{title}.md", "w") as f:
f.write(output)
空行をすべて除外してしまうと、テーブル直後のテキストがテーブルの一部と誤認識されてしまいます。そのため連続した空行のみ削りました。
まとめ
以上、PythonでConfluenceページをMarkdownに変換する方法についてでした。プライベート環境でコンフルページにアクセスできないため、変換前後の比較や出力されたMarkdownのサンプルをお見せできませんが、なかなか良い感じに変換されます。実際、業務でRAG用データをPDFからMarkdownに切り替えたところ、RAGの応答精度が格段に向上しました。
Header Photo by Unsplash Alex Chumak