見出し画像

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

処理の概要

  1. Confluenceページにアクセス: Selenium(ただし、2要素認証が必要な場合は一部手動入力あり)

  2. HTMLソース取得: Selenium

  3. HTMLのパース: Beautiful Soup

  4. Markdownへの変換: markdownify

  5. ファイル出力

手順

ここでは、ページアクセス時に「アカウント/パスワード入力」 + 「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

この記事が気に入ったらサポートをしてみませんか?