| | 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枚の長い画像にする。 |
| | """ |
| |
|
| | |
| | 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) |
| |
|
| | |
| | |
| | driver.execute_script( |
| | "document.documentElement.style.overflow = 'hidden';" |
| | "document.body.style.overflow = 'hidden';" |
| | ) |
| | 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="Full Page Screenshot with Scrolling", |
| | description=( |
| | "ページを少しずつスクロールしながら複数回キャプチャを撮影し、" |
| | "最終的に縦に結合して1枚の長い画像を生成します。" |
| | ) |
| | ) |
| |
|
| | if __name__ == "__main__": |
| | iface.launch() |
| |
|