HTMLviewer2 / app.py
tomo2chin2's picture
Update app.py
59a7627 verified
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()