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): # 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) ウィンドウサイズをページ全体に合わせる # 少し余裕をもたせるため+50などしてもOK driver.set_window_size(scroll_width, scroll_height) time.sleep(2) # レイアウトが変わるので少し待つ # 念のためページ最上部にスクロール driver.execute_script("window.scrollTo(0, 0)") time.sleep(1) # 8) スクリーンショットを取得 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) # 9) PNGバイナリをPIL.Imageに変換して返す return Image.open(BytesIO(png)) # Gradioインターフェース iface = gr.Interface( fn=render_fullpage_screenshot, inputs=gr.Textbox(lines=15, label="HTMLコード入力"), outputs=gr.Image(type="pil", label="ページ全体のスクリーンショット"), title="Full Page Screenshot App", description="HTMLをヘッドレスブラウザでレンダリングし、ページ全体を1枚の画像として取得します。" ) if __name__ == "__main__": iface.launch()