Zhofang commited on
Commit
bb3c19e
·
verified ·
1 Parent(s): 9ac6890

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +175 -0
app.py ADDED
@@ -0,0 +1,175 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import time
3
+ import gradio as gr
4
+ from selenium import webdriver
5
+ from selenium.webdriver.chrome.options import Options
6
+ from selenium.webdriver.support.ui import WebDriverWait
7
+ from selenium.webdriver.support import expected_conditions as EC
8
+ from selenium.webdriver.common.by import By
9
+ import tempfile
10
+ import logging
11
+
12
+ # Konfigurasi logging dasar
13
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
14
+
15
+ # Function to capture a screenshot with configurable options
16
+ def capture_screenshot_gradio(url, window_width, window_height, internal_delay):
17
+ """
18
+ Mengambil screenshot halaman web dengan ukuran jendela dan delay yang bisa diatur.
19
+
20
+ Args:
21
+ url (str): URL halaman web yang akan di-screenshot.
22
+ window_width (int): Lebar jendela browser dalam pixel.
23
+ window_height (int): Tinggi jendela browser dalam pixel.
24
+ internal_delay (int): Waktu tunggu tambahan (detik) setelah readyState 'complete'.
25
+
26
+ Returns:
27
+ str: Path ke file screenshot sementara.
28
+
29
+ Raises:
30
+ gr.Error: Jika terjadi kesalahan saat mengambil screenshot.
31
+ """
32
+ # Validasi URL sederhana atau tambahkan 'http://' jika tidak ada
33
+ if not url.startswith(('http://', 'https://')):
34
+ logging.info(f"Menambahkan 'http://' ke URL: {url}")
35
+ url = 'http://' + url
36
+
37
+ # Pastikan width dan height adalah integer
38
+ try:
39
+ window_width = int(window_width)
40
+ window_height = int(window_height)
41
+ internal_delay = int(internal_delay) # Delay juga harus integer
42
+ if window_width <= 0 or window_height <= 0 or internal_delay < 0:
43
+ raise ValueError("Width, Height harus positif dan Delay tidak boleh negatif")
44
+ except (ValueError, TypeError) as e:
45
+ logging.error(f"Input tidak valid untuk ukuran/delay: {e}")
46
+ raise gr.Error(f"Input tidak valid: Lebar, Tinggi harus angka positif dan Delay tidak boleh negatif.")
47
+
48
+ logging.info(f"Opsi yang digunakan: Lebar={window_width}, Tinggi={window_height}, Delay={internal_delay} detik")
49
+
50
+ chrome_options = Options()
51
+ chrome_options.add_argument('--headless')
52
+ chrome_options.add_argument('--disable-gpu')
53
+ chrome_options.add_argument('--no-sandbox')
54
+ # Mengatur ukuran jendela sesuai input pengguna
55
+ chrome_options.add_argument(f'--window-size={window_width},{window_height}')
56
+ chrome_options.add_argument('--disable-dev-shm-usage')
57
+ chrome_options.add_argument('--remote-debugging-port=9222') # Opsi ini mungkin tidak selalu diperlukan
58
+
59
+ driver = None
60
+ screenshot_path = None
61
+
62
+ try:
63
+ logging.info("Menginisialisasi WebDriver Chrome...")
64
+ # Pertimbangkan menggunakan webdriver-manager jika ChromeDriver tidak ada di PATH
65
+ # from selenium.webdriver.chrome.service import Service as ChromeService
66
+ # from webdriver_manager.chrome import ChromeDriverManager
67
+ # service = ChromeService(executable_path=ChromeDriverManager().install())
68
+ # driver = webdriver.Chrome(service=service, options=chrome_options)
69
+ driver = webdriver.Chrome(options=chrome_options)
70
+
71
+ logging.info(f"Membuka URL: {url}")
72
+ driver.get(url)
73
+
74
+ # 1. Tunggu hingga status dokumen 'complete'
75
+ logging.info("Menunggu document.readyState menjadi 'complete'...")
76
+ WebDriverWait(driver, 30).until( # Timeout lebih lama untuk halaman kompleks
77
+ lambda d: d.execute_script('return document.readyState') == 'complete'
78
+ )
79
+ logging.info("document.readyState sudah 'complete'.")
80
+
81
+ # 2. Tambahkan delay internal setelah 'complete'
82
+ if internal_delay > 0:
83
+ logging.info(f"Menunggu delay tambahan selama {internal_delay} detik...")
84
+ time.sleep(internal_delay)
85
+ logging.info("Delay selesai.")
86
+ else:
87
+ logging.info("Tidak ada delay tambahan (0 detik).")
88
+
89
+ # Buat file sementara untuk menyimpan screenshot
90
+ with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as tmp_file:
91
+ screenshot_path = tmp_file.name
92
+
93
+ logging.info(f"Mengambil screenshot ke: {screenshot_path}")
94
+ # Ambil screenshot dari seluruh halaman (mungkin perlu scroll jika konten panjang,
95
+ # tapi save_screenshot biasanya mengambil viewport saat ini dalam mode headless)
96
+ driver.save_screenshot(screenshot_path)
97
+ logging.info("Screenshot berhasil diambil.")
98
+
99
+ return screenshot_path
100
+
101
+ except Exception as e:
102
+ logging.error(f"Terjadi kesalahan saat memproses URL {url}: {e}", exc_info=True)
103
+ if screenshot_path and os.path.exists(screenshot_path):
104
+ try:
105
+ os.remove(screenshot_path)
106
+ logging.info(f"Membersihkan file sementara yang gagal: {screenshot_path}")
107
+ except OSError as remove_err:
108
+ logging.error(f"Gagal menghapus file sementara {screenshot_path}: {remove_err}")
109
+ raise gr.Error(f"Gagal mengambil screenshot: {e}")
110
+
111
+ finally:
112
+ if driver:
113
+ logging.info("Menutup WebDriver...")
114
+ driver.quit()
115
+ logging.info("WebDriver ditutup.")
116
+
117
+ # --- Membuat Antarmuka Gradio ---
118
+
119
+ # 1. Definisikan Komponen Input
120
+ url_input = gr.Textbox(
121
+ label="Masukkan URL Website",
122
+ placeholder="contoh: https://www.google.com atau example.com"
123
+ )
124
+
125
+ width_input = gr.Number(
126
+ label="Lebar Jendela (px)",
127
+ value=1920, # Nilai default
128
+ minimum=300, # Lebar minimum yang masuk akal
129
+ step=10, # Langkah penambahan/pengurangan
130
+ info="Lebar viewport browser saat mengambil screenshot."
131
+ )
132
+
133
+ height_input = gr.Number(
134
+ label="Tinggi Jendela (px)",
135
+ value=1080, # Nilai default
136
+ minimum=200, # Tinggi minimum yang masuk akal
137
+ step=10, # Langkah penambahan/pengurangan
138
+ info="Tinggi viewport browser. Untuk halaman panjang, ini mungkin tidak menangkap seluruhnya."
139
+ )
140
+
141
+ delay_input = gr.Number(
142
+ label="Delay Tambahan (detik)",
143
+ value=5, # Nilai default
144
+ minimum=0, # Boleh 0 detik
145
+ step=1, # Langkah penambahan/pengurangan
146
+ info="Waktu tunggu ekstra setelah halaman 'lengkap' untuk membiarkan konten dinamis (mis. JavaScript) selesai dimuat."
147
+ )
148
+
149
+ # 2. Definisikan Komponen Output
150
+ output_image = gr.Image(
151
+ type="filepath", # Mengharapkan path file sebagai output
152
+ label="Hasil Screenshot"
153
+ )
154
+
155
+ # 3. Membuat instance Interface Gradio
156
+ iface = gr.Interface(
157
+ fn=capture_screenshot_gradio, # Fungsi yang akan dijalankan
158
+ inputs=[url_input, width_input, height_input, delay_input], # Daftar komponen input (sesuai urutan argumen fungsi)
159
+ outputs=output_image, # Komponen output
160
+ title="Pengambil Screenshot Website dengan Opsi",
161
+ description="Masukkan URL, atur ukuran jendela dan delay tambahan, lalu klik 'Submit' untuk mengambil screenshot. Delay membantu menangkap konten yang dimuat secara dinamis.",
162
+ allow_flagging='never',
163
+ examples=[
164
+ ["https://gradio.app", 1280, 720, 3],
165
+ ["https://github.com", 1920, 1080, 5],
166
+ ["https://www.google.com/maps", 1024, 768, 8] # Contoh dengan delay lebih lama
167
+ ]
168
+ )
169
+
170
+ # Menjalankan aplikasi Gradio
171
+ if __name__ == "__main__":
172
+ print("Menjalankan aplikasi Gradio...")
173
+ print("Pastikan Google Chrome dan ChromeDriver yang sesuai sudah terinstall.")
174
+ print("Anda mungkin perlu menginstal: pip install selenium webdriver-manager gradio")
175
+ iface.launch()