tomo2chin2 commited on
Commit
b975c56
·
verified ·
1 Parent(s): 0774b51

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +114 -56
app.py CHANGED
@@ -1,68 +1,126 @@
1
  import gradio as gr
2
- import helium
 
3
  from selenium import webdriver
4
  from selenium.webdriver.chrome.options import Options
5
- from selenium.webdriver.chrome.service import Service # Import Service
6
- from io import BytesIO
 
7
  from PIL import Image
8
- import os
9
 
10
-
11
- def capture_screenshot(url):
12
- """
13
- 指定された URL のスクリーンショットを撮り、PIL Image オブジェクトとして返す。
14
- """
 
 
 
 
15
  try:
16
- # Chrome options for headless browsing
17
- chrome_options = Options()
18
- chrome_options.add_argument("--headless") # Headless mode
19
- chrome_options.add_argument("--no-sandbox") # For security reasons on some platforms
20
- chrome_options.add_argument("--disable-dev-shm-usage") # Fixes /dev/shm out-of-memory issues
21
- chrome_options.add_argument("--window-size=1024,768") # Set a reasonable window size
22
- # chrome_options.binary_location = '/usr/bin/google-chrome' # これは不要 or 間違い
23
-
24
- # Use Service object (explicitly specify chromedriver path if needed)
25
- # Hugging Face Spaces should handle chromedriver automatically,
26
- # so we usually don't need to specify the path. But if it still fails,
27
- # we can try to find it and specify.
28
- # service = Service(executable_path="/path/to/chromedriver") # 通常は不要
29
- service = Service() # これで動くはず
30
-
31
- # Start the browser with helium (using the options and service)
32
- driver = helium.start_chrome(options=chrome_options, service=service)
33
- helium.go_to(url)
34
-
35
- # Get screenshot as bytes
36
- png_bytes = driver.get_screenshot_as_png()
37
-
38
- # Convert bytes to PIL Image
39
- image = Image.open(BytesIO(png_bytes))
40
-
41
- return image
42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  except Exception as e:
44
- # Handle errors gracefully.
45
- return f"Error: {e}" # Return the error message
46
  finally:
47
- try:
48
- helium.kill_browser() # Always kill the browser
49
- except:
50
- pass
51
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
 
53
- # Gradio Interface
54
- if __name__ == '__main__':
55
- iface = gr.Interface(
56
- fn=capture_screenshot,
57
- inputs=gr.Textbox(label="Enter URL", placeholder="https://www.example.com"),
58
- outputs=gr.Image(type="pil", label="Screenshot"),
59
- title="HTML Screenshot Capture",
60
- description="Enter a URL to capture a screenshot of the webpage.",
61
- examples=[
62
- ["https://www.google.com"],
63
- ["https://www.wikipedia.org"],
64
- ["https://www.github.com"]
65
- ],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  )
67
- # Disable caching (to avoid potential caching-related errors during development)
68
- iface.launch(server_name="0.0.0.0", server_port=7860, cache_examples=False)
 
 
1
  import gradio as gr
2
+ import os
3
+ import tempfile
4
  from selenium import webdriver
5
  from selenium.webdriver.chrome.options import Options
6
+ from selenium.common.exceptions import WebDriverException
7
+ import time
8
+ import base64
9
  from PIL import Image
10
+ import io
11
 
12
+ def setup_driver():
13
+ """ヘッドレスChromeドライバーをセットアップして返す"""
14
+ options = webdriver.ChromeOptions()
15
+ options.add_argument("--headless")
16
+ options.add_argument("--no-sandbox")
17
+ options.add_argument("--disable-dev-shm-usage")
18
+ # 一貫したスクリーンショットのためにウィンドウサイズを設定
19
+ options.add_argument("--window-size=1280,1024")
20
+
21
  try:
22
+ driver = webdriver.Chrome(options=options)
23
+ return driver
24
+ except WebDriverException as e:
25
+ print(f"WebDriverの初期化に失敗しました: {e}")
26
+ return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
 
28
+ def capture_screenshot(html_content, css_content=""):
29
+ """SeleniumでレンダリングされたHTMLコンテンツのスクリーンショットを撮影する"""
30
+ driver = setup_driver()
31
+ if not driver:
32
+ return None, "Chrome WebDriverの初期化に失敗しました"
33
+
34
+ try:
35
+ # 一時的なHTMLファイルを作成
36
+ with tempfile.NamedTemporaryFile(suffix='.html', delete=False) as f:
37
+ html_file = f.name
38
+ combined_html = f"""
39
+ <!DOCTYPE html>
40
+ <html>
41
+ <head>
42
+ <meta charset="UTF-8">
43
+ <style>
44
+ {css_content}
45
+ </style>
46
+ </head>
47
+ <body>
48
+ {html_content}
49
+ </body>
50
+ </html>
51
+ """
52
+ f.write(combined_html.encode('utf-8'))
53
+
54
+ # HTMLファイルに移動
55
+ driver.get(f"file://{html_file}")
56
+ time.sleep(1) # レンダリングの時間を確保
57
+
58
+ # スクリーンショットを撮影
59
+ screenshot = tempfile.NamedTemporaryFile(suffix='.png', delete=False)
60
+ driver.save_screenshot(screenshot.name)
61
+ screenshot.close()
62
+
63
+ # 表示用に画像を読み込む
64
+ img = Image.open(screenshot.name)
65
+
66
+ # 後始末
67
+ os.unlink(html_file)
68
+
69
+ return img, None
70
  except Exception as e:
71
+ return None, f"スクリーンショットの撮影時にエラーが発生しました: {str(e)}"
 
72
  finally:
73
+ driver.quit()
 
 
 
74
 
75
+ def render_html(html_code, css_code=""):
76
+ """HTMLコードをレンダリングしてスクリーンショットを撮影"""
77
+ # HTMLを画像に変換
78
+ image, error = capture_screenshot(html_code, css_code)
79
+
80
+ if error:
81
+ return None, gr.HTML(f"<div style='color: red;'>{error}</div>")
82
+
83
+ # Gradioの HTML コンポーネントでHTMLを表示
84
+ html_display = f"""
85
+ <div style="border: 1px solid #ddd; padding: 10px; margin-bottom: 20px;">
86
+ <h3>HTMLプレビュー:</h3>
87
+ <iframe srcdoc="{html_code.replace('"', '&quot;')}"
88
+ style="width: 100%; height: 300px; border: 1px solid #ddd;"></iframe>
89
+ </div>
90
+ """
91
+
92
+ return image, gr.HTML(html_display)
93
 
94
+ # Gradioインターフェースを作成
95
+ with gr.Blocks() as demo:
96
+ gr.Markdown("# HTMLレンダラー(スクリーンショット機能付き)")
97
+ gr.Markdown("以下にHTMLコードを入力して、ヘッドレスChromeでレンダリングしスクリーンショットを撮影します。")
98
+
99
+ with gr.Row():
100
+ with gr.Column():
101
+ html_input = gr.Textbox(
102
+ label="HTMLコード",
103
+ placeholder="ここにHTMLコードを入力...",
104
+ lines=10,
105
+ value="<h1>こんにちは、世界!</h1><p>これはSeleniumとヘッドレスChromeによるGradioのテストです。</p>"
106
+ )
107
+ css_input = gr.Textbox(
108
+ label="CSSコード(オプション)",
109
+ placeholder="ここにCSSコードを入力...",
110
+ lines=5,
111
+ value="body { font-family: 'Noto Sans JP', sans-serif; margin: 20px; } h1 { color: blue; }"
112
+ )
113
+ render_button = gr.Button("レンダリングしてスクリーンショットを撮影")
114
+
115
+ with gr.Column():
116
+ screenshot_output = gr.Image(label="スクリーンショット")
117
+ html_preview = gr.HTML(label="HTMLプレビュー")
118
+
119
+ render_button.click(
120
+ render_html,
121
+ inputs=[html_input, css_input],
122
+ outputs=[screenshot_output, html_preview]
123
  )
124
+
125
+ # アプリを起動
126
+ demo.launch()