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