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): tmp_file = tempfile.NamedTemporaryFile(suffix=".html", delete=False) tmp_path = tmp_file.name tmp_file.write(html_code.encode('utf-8')) tmp_file.close() 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) driver.set_window_size(1200, 800) driver.get("file://" + tmp_path) # ページロード待機 WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.TAG_NAME, "body")) ) time.sleep(2) # 固定要素を強制的に「static」にして、重複しにくくする driver.execute_script( """ const elems = document.querySelectorAll('*'); for (const e of elems) { const style = window.getComputedStyle(e); if (style.position === 'fixed' || style.position === 'sticky') { e.style.position = 'static'; } } """ ) time.sleep(1) # ページ高さを取得 viewport_height = driver.execute_script("return window.innerHeight") scroll_height = driver.execute_script("return document.body.scrollHeight") images = [] current_position = 0 while True: # スクリーンショット png = driver.get_screenshot_as_png() img = Image.open(BytesIO(png)) images.append(img) # 最下部まで行ったら終了 if current_position + viewport_height >= scroll_height: break # 次のスクロール位置へ移動 current_position += viewport_height driver.execute_script(f"window.scrollTo(0, {current_position})") time.sleep(1) # 縦方向に結合 total_width = max(img.width for img in images) total_height = sum(img.height for img in images) full_screenshot = Image.new('RGB', (total_width, total_height)) current_y = 0 for img in images: full_screenshot.paste(img, (0, current_y)) current_y += img.height except Exception as e: return Image.new('RGB', (1, 1), color=(0, 0, 0)) finally: driver.quit() if os.path.exists(tmp_path): os.remove(tmp_path) return full_screenshot iface = gr.Interface( fn=render_fullpage_screenshot, inputs=gr.Textbox(lines=15, label="HTMLコード入力"), outputs=gr.Image(type="pil", label="フルページスクリーンショット"), title="Scrolling Screenshot (Remove Fixed Elements)", description="固定要素をstaticに変更して、重複を防ぎつつページ全体をキャプチャします。" ) if __name__ == "__main__": iface.launch()