HanJun commited on
Commit
7fe908b
·
verified ·
1 Parent(s): 2c476a3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +54 -97
app.py CHANGED
@@ -15,20 +15,21 @@ from selenium.common.exceptions import TimeoutException, NoSuchElementException
15
  from concurrent.futures import ThreadPoolExecutor
16
  import threading
17
 
18
- # Hugging Face Space 환경 확인
19
- IS_HUGGINGFACE = os.getenv("SPACE_ID") is not None
20
- print(f'IS_HUGGINGFACE = {IS_HUGGINGFACE}')
 
 
 
 
 
 
21
 
22
- # Claude API 설정 (Hugging Face Secrets에서 가져오기)
23
  ANTHROPIC_API_KEY = os.getenv("ANTHROPIC_API_KEY")
24
 
25
- if not ANTHROPIC_API_KEY:
26
- print("ANTHROPIC_API_KEY가 설정되지 않음, Secret 확인 필요")
27
- else:
28
- print("Claude API 키 확인 완료")
29
-
30
- # Claude 클라이언트를 생성
31
  def create_claude_client():
 
32
  try:
33
  client = anthropic.Anthropic(api_key=ANTHROPIC_API_KEY)
34
  print("Claude API 클라이언트 생성 성공")
@@ -37,36 +38,25 @@ def create_claude_client():
37
  print(f"Claude API 클라이언트 생성 실패: {e}")
38
  return None
39
 
40
- # Google Trends 자동화 클래스
41
  class GoogleTrendsAutomator:
 
 
42
  def __init__(self):
43
  self.driver = None
44
-
45
- # Chrome 드라이버 설정
46
  def setup_driver(self):
 
47
  options = Options()
48
 
49
- # Hugging Face Space 환경 설정
50
- if IS_HUGGINGFACE:
51
- print("Hugging Face Space 환경, 헤드리스 모드로 실행")
52
- options.add_argument("--headless=new") # 새로운 헤드리스 모드
53
  options.add_argument("--no-sandbox")
54
  options.add_argument("--disable-dev-shm-usage")
55
  options.add_argument("--disable-gpu")
56
- options.add_argument("--disable-software-rasterizer")
57
- options.add_argument("--remote-debugging-port=9222")
58
- else:
59
  options.add_argument("--headless")
60
 
61
- # # 환경별 설정
62
- # if os.getenv("SPACE_ID"): # Hugging Face Space
63
- # options.add_argument("--headless")
64
- # options.add_argument("--no-sandbox")
65
- # options.add_argument("--disable-dev-shm-usage")
66
- # options.add_argument("--disable-gpu")
67
- # else: # 로컬 환경
68
- # options.add_argument("--headless")
69
-
70
  # 속도 최적화 설정
71
  options.add_argument("--window-size=1280,720") # 해상도 줄임
72
  options.add_argument("--disable-blink-features=AutomationControlled")
@@ -85,8 +75,7 @@ class GoogleTrendsAutomator:
85
 
86
  # 메모리 최적화
87
  options.add_argument("--memory-pressure-off")
88
- # options.add_argument("--max_old_space_size=4096")
89
- options.add_argument("--max_old_space_size=2048")# 메모리 제한
90
 
91
  # 이미지/CSS 비활성화로 로딩 속도 향상
92
  prefs = {
@@ -105,66 +94,34 @@ class GoogleTrendsAutomator:
105
  options.add_argument("--accept-lang=ko-KR,ko;q=0.9,en;q=0.8")
106
 
107
  try:
108
- # Hugging Face 환경에서는 webdriver-manager 우선 사용
109
- if IS_HUGGINGFACE:
110
- try:
111
- from webdriver_manager.chrome import ChromeDriverManager
112
- from selenium.webdriver.chrome.service import Service
113
-
114
- print("ChromeDriver 자동 설치 중...")
115
- service = Service(ChromeDriverManager().install())
116
- self.driver = webdriver.Chrome(service=service, options=options)
117
- print("ChromeDriver 설치 및 초기화 성공")
118
-
119
- except Exception as e:
120
- print(f"webdriver-manager 설치 실패: {e}")
121
- # 시스템 ChromeDriver 시도
122
- try:
123
- self.driver = webdriver.Chrome(options=options)
124
- print("시스템 ChromeDriver 사용 성공")
125
- except Exception as sys_e:
126
- print(f"시스템 ChromeDriver도 실패: {sys_e}")
127
- return False
128
- else:
129
- # 로컬 환경
130
- try:
131
- from webdriver_manager.chrome import ChromeDriverManager
132
- from selenium.webdriver.chrome.service import Service
133
-
134
- service = Service(ChromeDriverManager().install())
135
- self.driver = webdriver.Chrome(service=service, options=options)
136
- print("로컬 ChromeDriver 설치 성공")
137
- except:
138
- self.driver = webdriver.Chrome(options=options)
139
- print("로컬 시스템 ChromeDriver 사용")
140
- # # 여러 방법으로 ChromeDriver 시도
141
- # driver_created = False
142
-
143
- # # 방법 1: webdriver-manager 사용
144
- # try:
145
- # from webdriver_manager.chrome import ChromeDriverManager
146
- # from selenium.webdriver.chrome.service import Service
147
 
148
- # service = Service(ChromeDriverManager().install())
149
- # self.driver = webdriver.Chrome(service=service, options=options)
150
- # print("webdriver-manager로 ChromeDriver 자동 설치 성공")
151
- # driver_created = True
152
 
153
- # except Exception as wm_error:
154
- # print(f"webdriver-manager 실패: {wm_error}")
155
-
156
- # # 방법 2: 시스템 ChromeDriver 사용
157
- # if not driver_created:
158
- # try:
159
- # self.driver = webdriver.Chrome(options=options)
160
- # print("시스템 ChromeDriver 사용 성공")
161
- # driver_created = True
162
- # except Exception as sys_error:
163
- # print(f"시스템 ChromeDriver 실패: {sys_error}")
164
-
165
- # if not driver_created:
166
- # print("모든 ChromeDriver 초기화 방법 실패")
167
- # return False
168
 
169
  # 타임아웃 설정 (속도 최적화)
170
  self.driver.set_page_load_timeout(15) # 페이지 로딩 타임아웃 15초
@@ -186,8 +143,8 @@ class GoogleTrendsAutomator:
186
  print(f"드라이버 설정 최종 실패: {e}")
187
  return False
188
 
189
- # 빠르게 Element 찾기, Timeout 단축 고려
190
  def safe_find_element(self, selectors: list, timeout: int = 3):
 
191
  for selector_type, selector in selectors:
192
  try:
193
  if selector_type == "xpath":
@@ -209,8 +166,8 @@ class GoogleTrendsAutomator:
209
  continue
210
  return None
211
 
212
- # 즉시 클릭
213
  def safe_click(self, selectors: list, timeout: int = 3) -> bool:
 
214
  element = self.safe_find_element(selectors, timeout)
215
  if element:
216
  try:
@@ -225,8 +182,8 @@ class GoogleTrendsAutomator:
225
  return False
226
  return False
227
 
228
- # 병렬로 설정 변경 시도
229
  def parallel_change_settings(self, region: str, period: str, category: str, progress_callback=None) -> dict:
 
230
  results = {
231
  'region': False,
232
  'period': False,
@@ -265,8 +222,8 @@ class GoogleTrendsAutomator:
265
 
266
  return results
267
 
268
- # 지역 변경
269
  def change_region(self, target_region: str) -> bool:
 
270
  try:
271
  region_selectors = [
272
  ("xpath", "//button[@aria-label='대한민국, 위치 선택']"),
@@ -302,8 +259,8 @@ class GoogleTrendsAutomator:
302
  print(f"지역 변경 실패: {e}")
303
  return False
304
 
305
- # 기간 변경
306
  def change_time_period(self, target_period: str) -> bool:
 
307
  try:
308
  period_selectors = [
309
  ("xpath", "//button[contains(@aria-label, '기간 선택')]"),
@@ -338,8 +295,8 @@ class GoogleTrendsAutomator:
338
  print(f"기간 변경 실패: {e}")
339
  return False
340
 
341
- # 카테고리 ��경
342
  def change_category(self, target_category: str) -> bool:
 
343
  try:
344
  category_selectors = [
345
  ("xpath", "//button[contains(@aria-label, '카테고리 선택')]"),
@@ -377,8 +334,8 @@ class GoogleTrendsAutomator:
377
  print(f"카테고리 변경 실패: {e}")
378
  return False
379
 
380
- # Google Trends 캡처
381
  def capture_trends(self, region: str, period: str, category: str, progress_callback=None) -> Tuple[Optional[str], bool, str]:
 
382
  error_msg = ""
383
 
384
  try:
@@ -446,8 +403,8 @@ class GoogleTrendsAutomator:
446
  if self.driver:
447
  self.driver.quit()
448
 
449
- # Claude API로 스크린샷 분석
450
  def analyze_with_claude(screenshot_b64: str, region: str, period: str, category: str) -> str:
 
451
  try:
452
  # API 키 체크
453
  if not ANTHROPIC_API_KEY or ANTHROPIC_API_KEY == "your_api_key_here":
 
15
  from concurrent.futures import ThreadPoolExecutor
16
  import threading
17
 
18
+ # .env 파일 로드 (있는 경우)
19
+ try:
20
+ from dotenv import load_dotenv
21
+ load_dotenv()
22
+ print(".env 파일 로드 완료")
23
+ except ImportError:
24
+ print("python-dotenv가 설치되지 않았습니다. 환경변수를 수동으로 설정해주세요.")
25
+ except Exception as e:
26
+ print(f".env 파일 로드 중 오류: {e}")
27
 
28
+ # Claude API 설정
29
  ANTHROPIC_API_KEY = os.getenv("ANTHROPIC_API_KEY")
30
 
 
 
 
 
 
 
31
  def create_claude_client():
32
+ """Claude 클라이언트를 생성하는 함수 (빠른 버전)"""
33
  try:
34
  client = anthropic.Anthropic(api_key=ANTHROPIC_API_KEY)
35
  print("Claude API 클라이언트 생성 성공")
 
38
  print(f"Claude API 클라이언트 생성 실패: {e}")
39
  return None
40
 
 
41
  class GoogleTrendsAutomator:
42
+ """최적화된 Google Trends 자동화 클래스"""
43
+
44
  def __init__(self):
45
  self.driver = None
46
+
 
47
  def setup_driver(self):
48
+ """초고속 Chrome 드라이버 설정"""
49
  options = Options()
50
 
51
+ # 환경별 설정
52
+ if os.getenv("SPACE_ID"): # Hugging Face Space
53
+ options.add_argument("--headless")
 
54
  options.add_argument("--no-sandbox")
55
  options.add_argument("--disable-dev-shm-usage")
56
  options.add_argument("--disable-gpu")
57
+ else: # 로컬 환경
 
 
58
  options.add_argument("--headless")
59
 
 
 
 
 
 
 
 
 
 
60
  # 속도 최적화 설정
61
  options.add_argument("--window-size=1280,720") # 해상도 줄임
62
  options.add_argument("--disable-blink-features=AutomationControlled")
 
75
 
76
  # 메모리 최적화
77
  options.add_argument("--memory-pressure-off")
78
+ options.add_argument("--max_old_space_size=4096")
 
79
 
80
  # 이미지/CSS 비활성화로 로딩 속도 향상
81
  prefs = {
 
94
  options.add_argument("--accept-lang=ko-KR,ko;q=0.9,en;q=0.8")
95
 
96
  try:
97
+ # 여러 방법으로 ChromeDriver 시도
98
+ driver_created = False
99
+
100
+ # 방법 1: webdriver-manager 사용
101
+ try:
102
+ from webdriver_manager.chrome import ChromeDriverManager
103
+ from selenium.webdriver.chrome.service import Service
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
+ service = Service(ChromeDriverManager().install())
106
+ self.driver = webdriver.Chrome(service=service, options=options)
107
+ print("webdriver-manager로 ChromeDriver 자동 설치 성공")
108
+ driver_created = True
109
 
110
+ except Exception as wm_error:
111
+ print(f"webdriver-manager 실패: {wm_error}")
112
+
113
+ # 방법 2: 시스템 ChromeDriver 사용
114
+ if not driver_created:
115
+ try:
116
+ self.driver = webdriver.Chrome(options=options)
117
+ print("시스템 ChromeDriver 사용 성공")
118
+ driver_created = True
119
+ except Exception as sys_error:
120
+ print(f"시스템 ChromeDriver 실패: {sys_error}")
121
+
122
+ if not driver_created:
123
+ print("모든 ChromeDriver 초기화 방법 실패")
124
+ return False
125
 
126
  # 타임아웃 설정 (속도 최적화)
127
  self.driver.set_page_load_timeout(15) # 페이지 로딩 타임아웃 15초
 
143
  print(f"드라이버 설정 최종 실패: {e}")
144
  return False
145
 
 
146
  def safe_find_element(self, selectors: list, timeout: int = 3):
147
+ """초고속 요소 찾기 (타임아웃 단축)"""
148
  for selector_type, selector in selectors:
149
  try:
150
  if selector_type == "xpath":
 
166
  continue
167
  return None
168
 
 
169
  def safe_click(self, selectors: list, timeout: int = 3) -> bool:
170
+ """즉시 클릭 (대기 시간 최소화)"""
171
  element = self.safe_find_element(selectors, timeout)
172
  if element:
173
  try:
 
182
  return False
183
  return False
184
 
 
185
  def parallel_change_settings(self, region: str, period: str, category: str, progress_callback=None) -> dict:
186
+ """병렬로 설정 변경 시도 (실험적)"""
187
  results = {
188
  'region': False,
189
  'period': False,
 
222
 
223
  return results
224
 
 
225
  def change_region(self, target_region: str) -> bool:
226
+ """초고속 지역 변경"""
227
  try:
228
  region_selectors = [
229
  ("xpath", "//button[@aria-label='대한민국, 위치 선택']"),
 
259
  print(f"지역 변경 실패: {e}")
260
  return False
261
 
 
262
  def change_time_period(self, target_period: str) -> bool:
263
+ """초고속 기간 변경"""
264
  try:
265
  period_selectors = [
266
  ("xpath", "//button[contains(@aria-label, '기간 선택')]"),
 
295
  print(f"기간 변경 실패: {e}")
296
  return False
297
 
 
298
  def change_category(self, target_category: str) -> bool:
299
+ """초고속 카테고리 변경"""
300
  try:
301
  category_selectors = [
302
  ("xpath", "//button[contains(@aria-label, '카테고리 선택')]"),
 
334
  print(f"카테고리 변경 실패: {e}")
335
  return False
336
 
 
337
  def capture_trends(self, region: str, period: str, category: str, progress_callback=None) -> Tuple[Optional[str], bool, str]:
338
+ """Google Trends 캡처 (최적화된 버전)"""
339
  error_msg = ""
340
 
341
  try:
 
403
  if self.driver:
404
  self.driver.quit()
405
 
 
406
  def analyze_with_claude(screenshot_b64: str, region: str, period: str, category: str) -> str:
407
+ """Claude API로 스크린샷 분석 (최적화된 버전)"""
408
  try:
409
  # API 키 체크
410
  if not ANTHROPIC_API_KEY or ANTHROPIC_API_KEY == "your_api_key_here":