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()