HanJun commited on
Commit
37ff9f3
·
verified ·
1 Parent(s): a1cf316

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +64 -98
app.py CHANGED
@@ -25,10 +25,6 @@ last_update_time = None
25
  update_thread = None
26
  is_updating = False
27
 
28
- # 전역 브라우저 인스턴스
29
- global_playwright = None
30
- global_browser = None
31
-
32
  def get_claude_client():
33
  """Claude API 클라이언트 초기화"""
34
  api_key = os.getenv("ANTHROPIC_API_KEY")
@@ -52,88 +48,52 @@ def install_browsers():
52
  print(f"브라우저 설치 실패: {e}")
53
  return False
54
 
55
- def get_shared_browser():
56
- """공유 브라우저 인스턴스 반환 (재사용 최적화 + 안정성 강화)"""
57
- global global_playwright, global_browser
58
-
59
  try:
60
- # Playwright 인스턴스 초기화
61
- if global_playwright is None:
62
- print("Playwright 인스턴스 초기화...")
63
- global_playwright = sync_playwright().start()
64
- print("Playwright 초기화 완료")
65
-
66
- # 브라우저 인스턴스 확인 및 생성
67
- if global_browser is None or not global_browser.is_connected():
68
- print("브라우저 인스턴스 생성 중...")
69
-
70
- # 브라우저 실행 옵션
71
- browser_args = [
72
- '--no-sandbox',
73
- '--disable-dev-shm-usage',
74
- '--disable-gpu',
75
- '--disable-extensions',
76
- '--disable-web-security',
77
- '--disable-blink-features=AutomationControlled',
78
- '--disable-background-timer-throttling',
79
- '--disable-backgrounding-occluded-windows',
80
- '--disable-renderer-backgrounding',
81
- '--disable-features=TranslateUI',
82
- '--disable-ipc-flooding-protection'
83
- ]
84
-
85
- global_browser = global_playwright.chromium.launch(
86
- headless=True,
87
- args=browser_args
88
- )
89
- print("브라우저 인스턴스 생성 완료")
90
-
91
- # 연결 상태 재확인
92
- if global_browser.is_connected():
93
- print("브라우저 연결 상태 양호")
94
- return global_browser
95
- else:
96
- print("브라우저 연결 상태 불량, 재생성 시도")
97
- global_browser = None
98
- return get_shared_browser() # 재귀 호출로 재생성
99
 
100
  except Exception as e:
101
- print(f"브라우저 인스턴스 생성 실패: {str(e)}")
102
  print(f"상세 오류: {traceback.format_exc()}")
103
-
104
- # 실패시 정리하고 None 반환
105
- try:
106
- if global_browser:
107
- global_browser.close()
108
- if global_playwright:
109
- global_playwright.stop()
110
- except:
111
- pass
112
-
113
- global_browser = None
114
- global_playwright = None
115
- return None
116
-
117
- def cleanup_browser():
118
- """브라우저 정리"""
119
- global global_playwright, global_browser
120
- try:
121
- if global_browser:
122
- global_browser.close()
123
- global_browser = None
124
- if global_playwright:
125
- global_playwright.stop()
126
- global_playwright = None
127
- except:
128
- pass
129
 
130
  def capture_google_trends() -> Optional[Image.Image]:
131
- """Google Trends 스크린샷 캡처 (동적 로딩 대응)"""
 
 
132
  page = None
133
 
134
  try:
135
  print("Google Trends 스크린샷 시작...")
136
- browser = get_shared_browser()
 
 
137
  if not browser:
138
  print("브라우저 초기화 실패")
139
  return None
@@ -206,19 +166,34 @@ def capture_google_trends() -> Optional[Image.Image]:
206
  print(f"상세 오류: {traceback.format_exc()}")
207
  return None
208
  finally:
 
209
  if page:
210
  try:
211
  page.close()
212
  except:
213
  pass
 
 
 
 
 
 
 
 
 
 
214
 
215
  def capture_ezme_trends() -> Optional[Image.Image]:
216
- """rank.ezme.net 스크린샷 캡처 (동적 로딩 대응)"""
 
 
217
  page = None
218
 
219
  try:
220
  print("rank.ezme.net 스크린샷 시작...")
221
- browser = get_shared_browser()
 
 
222
  if not browser:
223
  print("브라우저 초기화 실패")
224
  return None
@@ -275,11 +250,22 @@ def capture_ezme_trends() -> Optional[Image.Image]:
275
  print(f"상세 오류: {traceback.format_exc()}")
276
  return None
277
  finally:
 
278
  if page:
279
  try:
280
  page.close()
281
  except:
282
  pass
 
 
 
 
 
 
 
 
 
 
283
 
284
  def analyze_google_trends_with_claude(image: Image.Image) -> str:
285
  """Google Trends 이미지 Claude 분석"""
@@ -463,21 +449,6 @@ def combine_analysis_results(google_analysis: str, ezme_analysis: str) -> str:
463
 
464
  {ezme_analysis}
465
  """
466
-
467
- # ---
468
-
469
- # ## 종합 분석 및 인사이트
470
-
471
- # ### 주요 공통 이슈
472
- # - Google Trends와 한국 포털에서 공통적으로 상위권에 나타나는 검색어들을 통해 현재 가장 뜨거운 이슈를 파악할 수 있습니다.
473
-
474
- # ### 플랫폼별 특성
475
- # - **Google Trends**: 전세계적 관심사와 장기적 트렌드 반영
476
- # - **한국 포털 (Zum, Nate, Google)**: 한국 사용자의 실시간 관심사와 즉시성 있는 이슈 반영
477
-
478
- # ### 시간대별 검색 패턴
479
- # - 각 시간대별로 나타나는 검색어 변화를 통해 한국 사용자들의 일상 패턴과 관심사 변화를 관찰할 수 있습니다.
480
-
481
 
482
  return combined_result
483
 
@@ -752,9 +723,6 @@ def main():
752
  else:
753
  print("Claude API 키 확인됨")
754
 
755
- # 종료시 브라우저 정리
756
- atexit.register(cleanup_browser)
757
-
758
  # 초기 통합 분석 수행
759
  print("초기 통합 분석 시작...")
760
  initial_success, _ = perform_parallel_analysis()
@@ -786,8 +754,6 @@ def main():
786
  except Exception as e:
787
  print(f"인터페이스 시작 실패: {e}")
788
  print(f"상세 오류: {traceback.format_exc()}")
789
- finally:
790
- cleanup_browser()
791
 
792
  if __name__ == "__main__":
793
  main()
 
25
  update_thread = None
26
  is_updating = False
27
 
 
 
 
 
28
  def get_claude_client():
29
  """Claude API 클라이언트 초기화"""
30
  api_key = os.getenv("ANTHROPIC_API_KEY")
 
48
  print(f"브라우저 설치 실패: {e}")
49
  return False
50
 
51
+ def create_browser_for_thread():
52
+ """스레드별 독립적인 브라우저 인스턴스 생성"""
 
 
53
  try:
54
+ print(f"[Thread {threading.current_thread().name}] 브라우저 인스턴스 생성 중...")
55
+
56
+ playwright = sync_playwright().start()
57
+
58
+ # 브라우저 실행 옵션
59
+ browser_args = [
60
+ '--no-sandbox',
61
+ '--disable-dev-shm-usage',
62
+ '--disable-gpu',
63
+ '--disable-extensions',
64
+ '--disable-web-security',
65
+ '--disable-blink-features=AutomationControlled',
66
+ '--disable-background-timer-throttling',
67
+ '--disable-backgrounding-occluded-windows',
68
+ '--disable-renderer-backgrounding',
69
+ '--disable-features=TranslateUI',
70
+ '--disable-ipc-flooding-protection'
71
+ ]
72
+
73
+ browser = playwright.chromium.launch(
74
+ headless=True,
75
+ args=browser_args
76
+ )
77
+
78
+ print(f"[Thread {threading.current_thread().name}] 브라우저 인스턴스 생성 완료")
79
+ return playwright, browser
 
 
 
 
 
 
 
 
 
 
 
 
 
80
 
81
  except Exception as e:
82
+ print(f"[Thread {threading.current_thread().name}] 브라우저 인스턴스 생성 실패: {str(e)}")
83
  print(f"상세 오류: {traceback.format_exc()}")
84
+ return None, None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
 
86
  def capture_google_trends() -> Optional[Image.Image]:
87
+ """Google Trends 스크린샷 캡처 (독립 브라우저 인스턴스 사용)"""
88
+ playwright = None
89
+ browser = None
90
  page = None
91
 
92
  try:
93
  print("Google Trends 스크린샷 시작...")
94
+
95
+ # 스레드별 독립 브라우저 생성
96
+ playwright, browser = create_browser_for_thread()
97
  if not browser:
98
  print("브라우저 초기화 실패")
99
  return None
 
166
  print(f"상세 오류: {traceback.format_exc()}")
167
  return None
168
  finally:
169
+ # 리소스 정리
170
  if page:
171
  try:
172
  page.close()
173
  except:
174
  pass
175
+ if browser:
176
+ try:
177
+ browser.close()
178
+ except:
179
+ pass
180
+ if playwright:
181
+ try:
182
+ playwright.stop()
183
+ except:
184
+ pass
185
 
186
  def capture_ezme_trends() -> Optional[Image.Image]:
187
+ """rank.ezme.net 스크린샷 캡처 (독립 브라우저 인스턴스 사용)"""
188
+ playwright = None
189
+ browser = None
190
  page = None
191
 
192
  try:
193
  print("rank.ezme.net 스크린샷 시작...")
194
+
195
+ # 스레드별 독립 브라우저 생성
196
+ playwright, browser = create_browser_for_thread()
197
  if not browser:
198
  print("브라우저 초기화 실패")
199
  return None
 
250
  print(f"상세 오류: {traceback.format_exc()}")
251
  return None
252
  finally:
253
+ # 리소스 정리
254
  if page:
255
  try:
256
  page.close()
257
  except:
258
  pass
259
+ if browser:
260
+ try:
261
+ browser.close()
262
+ except:
263
+ pass
264
+ if playwright:
265
+ try:
266
+ playwright.stop()
267
+ except:
268
+ pass
269
 
270
  def analyze_google_trends_with_claude(image: Image.Image) -> str:
271
  """Google Trends 이미지 Claude 분석"""
 
449
 
450
  {ezme_analysis}
451
  """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
452
 
453
  return combined_result
454
 
 
723
  else:
724
  print("Claude API 키 확인됨")
725
 
 
 
 
726
  # 초기 통합 분석 수행
727
  print("초기 통합 분석 시작...")
728
  initial_success, _ = perform_parallel_analysis()
 
754
  except Exception as e:
755
  print(f"인터페이스 시작 실패: {e}")
756
  print(f"상세 오류: {traceback.format_exc()}")
 
 
757
 
758
  if __name__ == "__main__":
759
  main()