tomo2chin2 commited on
Commit
a7ae2e2
·
verified ·
1 Parent(s): e9215e2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +49 -66
app.py CHANGED
@@ -7,48 +7,43 @@ import os
7
  from PIL import Image
8
  import time
9
  import base64
10
- import validators # URLバリデーション用
11
 
12
 
13
- def take_screenshot(url_or_html, wait_time=3, screenshot_type="url"):
14
  """
15
- URLまたはHTMLコードからフルページスクリーンショットを取得する関数。
 
16
 
17
  Args:
18
- url_or_html (str): スクリーンショットを取得するURLまたはHTMLコード。
19
  wait_time (int): ページ読み込みの待機時間(秒)。
20
- screenshot_type (str): "url" または "html" を指定。
21
 
22
  Returns:
23
- tuple: (PIL.Image.Image, str) スクリーンショット画像とメッセージのタプル。
24
  エラーの場合は (None, str) を返す。
25
  """
26
  options = Options()
27
- options.add_argument("--headless=new") # 新しいヘッドレスモード
28
  options.add_argument("--no-sandbox")
29
  options.add_argument("--disable-dev-shm-usage")
30
  options.add_argument("--disable-gpu")
31
- options.add_argument("--window-position=-2400,-2400") # Windowsでのバグ回避
 
 
32
 
33
  try:
34
  driver = webdriver.Chrome(options=options)
 
 
35
 
36
- if screenshot_type == "url":
37
- # URLバリデーション
38
- if not validators.url(url_or_html):
39
- raise ValueError("無効なURLです。")
40
- driver.get(url_or_html)
41
-
42
- elif screenshot_type == "html":
43
- # HTMLをbase64にエンコードしてdata URLとして読み込む
44
- html_base64 = base64.b64encode(url_or_html.encode('utf-8')).decode('utf-8')
45
- driver.get(f"data:text/html;base64,{html_base64}")
46
- else:
47
- raise ValueError("screenshot_typeは'url'または'html'を指定してください。")
48
 
49
- time.sleep(wait_time) # ページの読み込みを待機
 
 
 
50
 
51
- # フルページサイズを取得 (JavaScript)
52
  width = driver.execute_script(
53
  "return Math.max(document.body.scrollWidth, document.body.offsetWidth, "
54
  "document.documentElement.clientWidth, document.documentElement.scrollWidth, "
@@ -60,59 +55,47 @@ def take_screenshot(url_or_html, wait_time=3, screenshot_type="url"):
60
  "document.documentElement.offsetHeight);"
61
  )
62
 
63
- # ウィンドウサイズを設定(巨大なページに対する制限付き)
64
- driver.set_window_size(min(width + 100, 1920), min(height + 100, 5000)) # 最大幅1920px, 最大高さ5000px
65
- time.sleep(1) # レンダリング待機
 
 
 
 
 
 
66
 
67
- # スクリーンショットを一時ファイルに保存
68
  with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as temp:
69
  temp_filename = temp.name
70
  driver.save_screenshot(temp_filename)
71
-
72
- driver.quit()
73
-
74
- # 画像を読み込んで返す
75
  image = Image.open(temp_filename)
76
- os.unlink(temp_filename) # 一時ファイルを削除
77
-
78
  return image, "スクリーンショットを取得しました。"
79
 
80
- except (WebDriverException, TimeoutException, ValueError) as e:
81
- driver.quit()
82
  return None, f"エラー: {str(e)}"
83
  except Exception as e:
84
- driver.quit()
85
  return None, f"予期しないエラー: {str(e)}"
86
-
87
- # Gradioインターフェース (URLとHTMLの両方に対応)
88
- with gr.Blocks(title="Web Screenshot Tool") as demo:
89
- gr.Markdown("# ウェブページ & HTML スクリーンショットツール")
90
- gr.Markdown("URLまたはHTMLコードを入力して、フルページのスクリーンショットを取得します。")
91
-
92
- with gr.Tab("URLから取得"):
93
- url_input = gr.Textbox(label="URL", placeholder="https://example.com")
94
- url_wait_time = gr.Slider(minimum=1, maximum=10, value=3, step=1, label="待機時間 (秒)")
95
- url_button = gr.Button("スクリーンショットを取得 (URL)")
96
- url_image_out = gr.Image(label="スクリーンショット (URL)")
97
- url_text_out = gr.Textbox(label="結果 (URL)")
98
-
99
- url_button.click(
100
- take_screenshot,
101
- inputs=[url_input, url_wait_time, gr.State("url")], # "url"を指定
102
- outputs=[url_image_out, url_text_out]
103
- )
104
-
105
- with gr.Tab("HTMLから取得"):
106
- html_input = gr.Textbox(label="HTMLコード", placeholder="<p>Hello, world!</p>", lines=5)
107
- html_wait_time = gr.Slider(minimum=1, maximum=10, value=3, step=1, label="待機時間 (秒)")
108
- html_button = gr.Button("スクリーンショットを取得 (HTML)")
109
- html_image_out = gr.Image(label="スクリーンショット (HTML)")
110
- html_text_out = gr.Textbox(label="結果 (HTML)")
111
-
112
- html_button.click(
113
- take_screenshot,
114
- inputs=[html_input, html_wait_time, gr.State("html")], # "html"を指定
115
- outputs=[html_image_out, html_text_out]
116
- )
117
 
118
  demo.launch()
 
7
  from PIL import Image
8
  import time
9
  import base64
 
10
 
11
 
12
+ def take_screenshot_from_html(html_code, wait_time=3):
13
  """
14
+ HTMLコードからフルページスクリーンショットを取得する関数。
15
+ キャプチャ前に高さを3%拡張し、スクロールバーの有無に応じて調整。
16
 
17
  Args:
18
+ html_code (str): スクリーンショットを取得するHTMLコード。
19
  wait_time (int): ページ読み込みの待機時間(秒)。
 
20
 
21
  Returns:
22
+ tuple: (PIL.Image.Image, str) スクリーンショット画像とメッセージ。
23
  エラーの場合は (None, str) を返す。
24
  """
25
  options = Options()
26
+ options.add_argument("--headless=new")
27
  options.add_argument("--no-sandbox")
28
  options.add_argument("--disable-dev-shm-usage")
29
  options.add_argument("--disable-gpu")
30
+ options.add_argument("--window-position=-2400,-2400") # Windowsでのバグ回避
31
+
32
+ driver = None # driverをtryの外で初期化
33
 
34
  try:
35
  driver = webdriver.Chrome(options=options)
36
+ html_base64 = base64.b64encode(html_code.encode('utf-8')).decode('utf-8')
37
+ driver.get(f"data:text/html;base64,{html_base64}")
38
 
39
+ time.sleep(wait_time)
 
 
 
 
 
 
 
 
 
 
 
40
 
41
+ # スクロールバーの有無をチェック
42
+ has_scrollbar = driver.execute_script(
43
+ "return document.documentElement.scrollHeight > document.documentElement.clientHeight;"
44
+ )
45
 
46
+ # ページサイズを取得
47
  width = driver.execute_script(
48
  "return Math.max(document.body.scrollWidth, document.body.offsetWidth, "
49
  "document.documentElement.clientWidth, document.documentElement.scrollWidth, "
 
55
  "document.documentElement.offsetHeight);"
56
  )
57
 
58
+ # 高さを3%拡張(スクロールバーがあればさらに調整)
59
+ extra_height = int(height * 0.03)
60
+ if has_scrollbar:
61
+ final_height = min(height + extra_height + 20, 5000) # スクロールバー分を考慮、最大5000px
62
+ else:
63
+ final_height = min(height + extra_height, 5000) # スクロールバーがなければ3%のみ、最大5000px
64
+
65
+ driver.set_window_size(min(width + 100, 1920), final_height) # 最大幅1920
66
+ time.sleep(1)
67
 
 
68
  with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as temp:
69
  temp_filename = temp.name
70
  driver.save_screenshot(temp_filename)
 
 
 
 
71
  image = Image.open(temp_filename)
72
+ os.unlink(temp_filename)
 
73
  return image, "スクリーンショットを取得しました。"
74
 
75
+ except (WebDriverException, TimeoutException) as e:
 
76
  return None, f"エラー: {str(e)}"
77
  except Exception as e:
 
78
  return None, f"予期しないエラー: {str(e)}"
79
+ finally:
80
+ if driver: # driverが存在する場合のみquit()を実行
81
+ driver.quit()
82
+
83
+
84
+ # Gradioインターフェース (HTML専用)
85
+ with gr.Blocks(title="HTML Screenshot Tool") as demo:
86
+ gr.Markdown("# HTML スクリーンショットツール")
87
+ gr.Markdown("HTMLコードを入力して、レンダリングされたページのフルスクリーンショットを取得します。")
88
+
89
+ html_input = gr.Textbox(label="HTMLコード", placeholder="<p>Hello, world!</p>", lines=5)
90
+ wait_time_slider = gr.Slider(minimum=1, maximum=10, value=3, step=1, label="待機時間 ()")
91
+ screenshot_button = gr.Button("スクリーンショットを取得")
92
+ image_output = gr.Image(label="スクリーンショット")
93
+ text_output = gr.Textbox(label="結果")
94
+
95
+ screenshot_button.click(
96
+ take_screenshot_from_html,
97
+ inputs=[html_input, wait_time_slider],
98
+ outputs=[image_output, text_output]
99
+ )
 
 
 
 
 
 
 
 
 
 
100
 
101
  demo.launch()