Spaces:
Paused
Paused
| import gradio as gr | |
| from selenium import webdriver | |
| from selenium.webdriver.chrome.options import Options | |
| from selenium.webdriver.common.by import By | |
| from selenium.webdriver.support.ui import WebDriverWait | |
| from selenium.webdriver.support import expected_conditions as EC | |
| from PIL import Image | |
| from io import BytesIO | |
| import tempfile | |
| import time | |
| import os | |
| def render_fullpage_screenshot(html_code, extension_percentage): | |
| """ | |
| html_code: HTMLのソースコード文字列 | |
| extension_percentage: 上下に追加する余裕の% (例: 4なら合計4%の余裕) | |
| """ | |
| # 1) HTMLコードを一時ファイルに保存 | |
| tmp_file = tempfile.NamedTemporaryFile(suffix=".html", delete=False) | |
| tmp_path = tmp_file.name | |
| tmp_file.write(html_code.encode('utf-8')) | |
| tmp_file.close() | |
| # 2) ヘッドレスChrome(Chromium)起動オプション | |
| options = Options() | |
| options.add_argument("--headless") | |
| options.add_argument("--no-sandbox") | |
| options.add_argument("--disable-dev-shm-usage") | |
| options.add_argument("--force-device-scale-factor=1") | |
| try: | |
| driver = webdriver.Chrome(options=options) | |
| # 3) 初期ウィンドウサイズでページを読み込む | |
| driver.set_window_size(1200, 800) | |
| driver.get("file://" + tmp_path) | |
| # 4) ページのロードを待機 | |
| WebDriverWait(driver, 10).until( | |
| EC.presence_of_element_located((By.TAG_NAME, "body")) | |
| ) | |
| time.sleep(2) # 外部リソースの読み込み待機 | |
| # 5) スクロールバーがキャプチャに写らないようCSSで非表示 | |
| driver.execute_script( | |
| "document.documentElement.style.overflow = 'hidden';" | |
| "document.body.style.overflow = 'hidden';" | |
| ) | |
| # 6) ページ全体の幅・高さを正確に取得 (bodyとdocumentElementの両方から) | |
| scroll_width = driver.execute_script( | |
| "return Math.max(document.body.scrollWidth, document.documentElement.scrollWidth)" | |
| ) | |
| scroll_height = driver.execute_script( | |
| "return Math.max(document.body.scrollHeight, document.documentElement.scrollHeight)" | |
| ) | |
| # 7) 上下方向にだけユーザー指定の余裕(%)を加えた高さを計算 | |
| adjusted_height = int(scroll_height * (1 + extension_percentage/100)) | |
| # 8) ウィンドウサイズを、幅はそのまま、縦はadjusted_heightに変更 | |
| driver.set_window_size(scroll_width, adjusted_height) | |
| time.sleep(2) # レイアウトの安定化待機 | |
| # 念のため最上部にスクロール | |
| driver.execute_script("window.scrollTo(0, 0)") | |
| time.sleep(1) | |
| # 9) スクリーンショット取得 | |
| png = driver.get_screenshot_as_png() | |
| except Exception as e: | |
| # エラー時は1x1の黒画像を返す | |
| return Image.new('RGB', (1, 1), color=(0, 0, 0)) | |
| finally: | |
| driver.quit() | |
| if os.path.exists(tmp_path): | |
| os.remove(tmp_path) | |
| return Image.open(BytesIO(png)) | |
| # Gradioインターフェースの定義 | |
| iface = gr.Interface( | |
| fn=render_fullpage_screenshot, | |
| inputs=[ | |
| gr.Textbox(lines=15, label="HTMLコード入力"), | |
| gr.Slider(minimum=0, maximum=20, step=1.0, value=8, label="上下高さ拡張率(%)") | |
| ], | |
| outputs=gr.Image(type="pil", label="ページ全体のスクリーンショット"), | |
| title="Full Page Screenshot App (高さ拡張調整可能)", | |
| description="HTMLをヘッドレスブラウザでレンダリングし、ページ全体を1枚の画像として取得します。上下のみユーザー指定の余裕(%)を追加します。" | |
| ) | |
| if __name__ == "__main__": | |
| iface.launch() | |