PythonでWikipediaをスクレイピングし、Markdownに変換する方法

チュートリアル

この記事では、Pythonを使用して特定のWikipediaページからコンテンツを取得し、不要な部分を削除・整形した上で、Markdownファイルとして保存するスクリプトについて解説します。WebスクレイピングライブラリのrequestsBeautifulSoup、そしてHTMLをMarkdownに変換するhtml2textを使用します。

概要

このスクリプトの主な目的は、Wikipediaのコンテンツを機械可読性の高いMarkdown形式で取得することです。具体的には、以下の処理を自動化します。

  • 指定したURLのWikipediaページからHTMLコンテンツを取得します。
  • ページのタイトルを抽出し、MarkdownのH1見出し(#)として設定します。
  • 本文中の特定のタグ(例:「登場人物」などで使われる<dt>タグ)を見出しに変換し、構造を維持します。
  • 「脚注」や「編集」リンクなど、記事本文とは直接関係のない要素を削除します。
  • 最終的に整形されたコンテンツを、ローカルにMarkdownファイル(.md)として保存します。

準備:必要なライブラリのインストール

このスクリプトを実行するには、いくつかのPythonライブラリが必要です。以下のコマンドを使用してインストールしてください。

pip install requests beautifulsoup4 html2text
  • requests: HTTPリクエストを送信し、WebページからHTMLを取得するために使用します。
  • beautifulsoup4: HTMLやXMLファイルをパース(解析)し、データの抽出を容易にするために使用します。
  • html2text: HTMLコンテンツをMarkdown形式のテキストに変換するために使用します。

実装:スクレイピングとMarkdown変換のコード

以下が、Wikipediaページを整形されたMarkdownに変換するメインのPythonスクリプトです。

import requests
from bs4 import BeautifulSoup
import html2text
import re

def scrape_wikipedia_to_markdown_final(url: str) -> str:
    """
    Wikipediaページをスクレイピングし、整形・不要部分削除を行い、
    タイトルを付けてMarkdownに変換します。

    処理フロー:
    1. ページのタイトルをH1見出しとして取得します。
    2. 「登場人物」などの<dt>タグを見出しに変換します。
    3. 生成されたMarkdown文字列から「## 脚注」以降を完全に削除します。
    4. [編集]リンクを削除します。
    5. 最終的にタイトルと本文を結合して返します。

    Args:
        url (str): スクレイピング対象のWikipediaページのURL。

    Returns:
        str: 整形・変換された最終的なMarkdownコンテンツ。失敗した場合は空の文字列。
    """
    try:
        # 1. HTMLの取得と解析
        response = requests.get(url)
        response.raise_for_status()  # HTTPエラーがあれば例外を発生させる
        soup = BeautifulSoup(response.content, 'html.parser')

        # --- ページのタイトルを取得 ---
        title_tag = soup.find('h1', id='firstHeading')
        page_title = title_tag.get_text(strip=True) if title_tag else "Wikipedia ページ"

        # 2. 主要コンテンツエリアの特定
        content_div = soup.find('div', class_='mw-parser-output')
        if not content_div:
            print("エラー: コンテンツエリアが見つかりませんでした。")
            return ""

        # 3. HTMLの事前整形(登場人物などの見出し化)
        for dt_tag in content_div.find_all('dt'):
            h4_tag = soup.new_tag('h4')
            h4_tag.extend(dt_tag.contents)
            dt_tag.replace_with(h4_tag)

        # 4. HTMLからMarkdownへの一次変換
        h = html2text.HTML2Text()
        h.body_width = 0  # テキストの折り返しを無効にする
        full_markdown_text = h.handle(str(content_div))

        # 5. 生成されたMarkdownから「## 脚注」以降を削除
        footnote_marker = "\n## 脚注"
        footnote_index = full_markdown_text.find(footnote_marker)
        body_text = full_markdown_text[:footnote_index] if footnote_index != -1 else full_markdown_text

        # 6. [編集]リンクを正規表現で一括削除
        cleaned_body = re.sub(r'\[\[編集\]\(.+?\)]\n', '', body_text)

        # 7. タイトルと整形後の本文を結合
        final_markdown = f"# {page_title}\n\n{cleaned_body.strip()}"

        return final_markdown

    except requests.exceptions.RequestException as e:
        print(f"HTTPリクエストエラー: {e}")
        return ""
    except Exception as e:
        print(f"予期せぬエラーが発生しました: {e}")
        return ""

if __name__ == '__main__':
    # 対象のWikipediaページのURLを指定
    WIKIPEDIA_URL = "https://ja.wikipedia.org/wiki/%E6%9D%B1%E6%96%B9%E5%9C%B0%E9%9C%8A%E6%AE%BF_%E3%80%9C_Subterranean_Animism."

    # スクレイピングと最終的な整形を実行
    markdown_content = scrape_wikipedia_to_markdown_final(WIKIPEDIA_URL)

    if markdown_content:
        # 結果をコンソールに出力
        # print(markdown_content)

        # ファイルに保存
        output_filename = "Touhou_Chireiden.md"
        with open(output_filename, "w", encoding="utf-8") as f:
            f.write(markdown_content)
        print(f"Markdownファイル '{output_filename}' に保存しました。")

まとめ

このスクリプトで達成できたこと

  • 指定したWikipediaページ(例:「東方地霊殿 〜 Subterranean Animism.」)のコンテンツを、Pythonスクリプトを用いて取得できました。
  • 取得したコンテンツは、ページのタイトルを見出しとし、不要な脚注や編集リンクが除去された、クリーンなMarkdown形式に整形されています。
  • 整形後のコンテンツは、UTF-8エンコーディングで指定したファイル名(例:Touhou_Chireiden.md)に正しく保存されます。

📒ノートブック

Google Colab

コメント

タイトルとURLをコピーしました