File size: 4,501 Bytes
a050721
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import gradio as gr
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager
from markdownify import markdownify as md
import time

def fetch_and_convert_to_markdown(url: str):
    """
    指定されたURLからWebページのHTMLを取得し、Markdown形式に変換する関数。
    
    Args:
        url (str): 取得したいWebページのURL。
        
    Returns:
        str: Markdown形式に変換されたテキスト、またはエラーメッセージ。
    """
    if not url or not url.startswith(('http://', 'https://')):
        return "エラー: 有効なURLを入力してください (例: https://example.com)"

    print(f"URLの処理を開始します: {url}")
    
    # WebDriverを初期化するための変数
    driver = None
    
    try:
        # --- Seleniumのセットアップ ---
        # Chromeのオプションを設定
        options = Options()
        options.add_argument("--headless")  # ブラウザUIなしでバックグラウンド実行
        options.add_argument("--no-sandbox")
        options.add_argument("--disable-dev-shm-usage")
        options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")

        # webdriver-managerを使ってChromeDriverを自動でセットアップ
        service = Service(ChromeDriverManager().install())
        
        # WebDriverインスタンスを作成
        driver = webdriver.Chrome(service=service, options=options)
        
        # ページの読み込みタイムアウトを30秒に設定
        driver.set_page_load_timeout(30)
        
        # --- ページの取得 ---
        print("ページにアクセスしています...")
        driver.get(url)
        
        # JavaScriptで動的に読み込まれるコンテンツを待つため、数秒待機(任意)
        # time.sleep(3) 
        
        # ページのHTMLソースを取得
        html_content = driver.page_source
        print("HTMLの取得に成功しました。")

        # --- HTMLからMarkdownへの変換 ---
        print("Markdownへの変換を開始します...")
        # heading_style="ATX" は見出しを # や ## で表現するスタイルです
        markdown_content = md(html_content, heading_style="ATX")
        print("変換が完了しました。")
        
        return markdown_content

    except Exception as e:
        print(f"エラーが発生しました: {e}")
        return f"エラーが発生しました。\nURLが正しいか、ページが存在するか確認してください。\n\n詳細: {str(e)}"
    
    finally:
        # --- WebDriverの終了 ---
        # エラーが発生しても必ずブラウザを閉じる
        if driver:
            driver.quit()
            print("WebDriverを終了しました。")


# --- Gradio UIの構築 ---
with gr.Blocks(theme=gr.themes.Soft()) as demo:
    gr.Markdown(
        """
        # WebページをMarkdownに変換するアプリ
        URLを入力すると、そのページの内容をAIが読みやすいMarkdown形式で取得します。
        """
    )
    
    with gr.Row():
        url_input = gr.Textbox(
            label="URL",
            placeholder="例: https://ja.wikipedia.org/wiki/Markdown",
            scale=4, # 横幅の比率
        )
        submit_button = gr.Button("取得開始", variant="primary", scale=1)

    output_markdown = gr.Textbox(
        label="取得結果 (Markdown)",
        lines=20,
        interactive=False, # ユーザーが直接編集できないようにする
        show_copy_button=True, # コピーボタンを表示
    )
    
    # ボタンがクリックされた時の動作を定義
    submit_button.click(
        fn=fetch_and_convert_to_markdown,
        inputs=url_input,
        outputs=output_markdown
    )
    
    gr.Examples(
        examples=[
            "https://www.gradio.app/",
            "https://github.com/gradio-app/gradio",
            "https://huggingface.co/blog/gradio-guides-jp"
        ],
        inputs=url_input,
        fn=fetch_and_convert_to_markdown,
        outputs=output_markdown,
        cache_examples=True # 例の結果をキャッシュして高速化
    )

# アプリケーションの起動
if __name__ == "__main__":
    demo.launch()