hzruo commited on
Commit
461b6d3
·
verified ·
1 Parent(s): ea6a675

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +174 -87
main.py CHANGED
@@ -15,10 +15,9 @@ import tempfile
15
  import os
16
  import re
17
  import threading
18
- from DrissionPage import ChromiumPage, ChromiumOptions
19
- from DrissionPage.common import Settings
20
  import logging
21
  from dotenv import load_dotenv
 
22
 
23
  # 加载环境变量
24
  load_dotenv(override=True)
@@ -30,10 +29,6 @@ logging.basicConfig(
30
  )
31
  logger = logging.getLogger(__name__)
32
 
33
- # 全局配置 DrissionPage 设置
34
- Settings.set_browser_connect_timeout(60) # 增加连接超时时间
35
- Settings.set_language('en') # 设置错误信息为英文,方便调试
36
-
37
  # 修改全局数据存储
38
  global_data = {
39
  "cookie": None,
@@ -45,13 +40,40 @@ global_data = {
45
  @asynccontextmanager
46
  async def lifespan(app: FastAPI):
47
  # 启动时获取 cookie
48
- threading.Thread(target=get_cookie).start()
 
 
 
 
 
 
 
49
  yield
 
50
  # 关闭时清理资源
 
51
  global_data["cookie"] = None
52
  global_data["cookies"] = None
53
  global_data["last_update"] = 0
54
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  app = FastAPI(lifespan=lifespan)
56
  security = HTTPBearer()
57
 
@@ -64,83 +86,132 @@ def get_cookie():
64
  try:
65
  logger.info("Starting cookie retrieval process...")
66
 
67
- # 创建配置对象
68
- options = ChromiumOptions()
69
-
70
- # 设置浏览器路径
71
- chrome_path = os.getenv('CHROME_PATH', '/usr/bin/google-chrome-stable')
72
- logger.info(f"Using Chrome path: {chrome_path}")
73
- options.set_browser_path(chrome_path)
74
-
75
- # 设置用户数据目录
76
- user_data_dir = os.getenv('CHROME_USER_DATA_DIR', '/tmp/chrome-data')
77
- logger.info(f"Using user data directory: {user_data_dir}")
78
- options.set_user_data_path(user_data_dir)
79
-
80
- # 使用自动端口分配
81
- logger.info("Using auto port allocation")
82
- options.auto_port(True)
83
-
84
- # 设置无头模式和其他参数
85
- options.headless() # 使用 headless() 方法设置无头模式
86
- options.set_argument('--headless=new') # 使用新的无头模式
87
- options.set_argument('--no-sandbox') # Linux 系统必需
88
- options.set_argument('--disable-dev-shm-usage')
89
- options.set_argument('--disable-gpu')
90
- options.set_argument('--disable-software-rasterizer')
91
- options.set_argument('--disable-extensions')
92
- options.set_argument('--disable-setuid-sandbox')
93
- options.set_argument('--no-first-run')
94
- options.set_argument('--no-zygote')
95
- options.set_argument('--single-process')
96
- options.set_argument('--window-size=1920,1080')
97
- options.set_argument('--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36')
98
-
99
- # 启用详细日志
100
- options.set_argument('--enable-logging')
101
- options.set_argument('--v=1')
102
-
103
- # 打印配置信息
104
- logger.info(f"Browser path: {options.browser_path}")
105
- logger.info(f"User data path: {options.user_data_path}")
106
- logger.info(f"Arguments: {options.arguments}")
107
-
108
- # 使用配置对象创建页面
109
- logger.info("Creating ChromiumPage instance...")
110
- page = ChromiumPage(options)
111
-
112
- logger.info("Navigating to target website...")
113
- page.get("https://chat.akash.network/")
114
-
115
- logger.info("Waiting for page load...")
116
- time.sleep(10)
117
-
118
- logger.info("Getting cookies...")
119
- cookies = page.cookies()
120
- if not cookies:
121
- logger.error("No cookies found")
122
- page.quit()
123
- return None
124
-
125
- cookie_dict = {cookie['name']: cookie['value'] for cookie in cookies}
126
- if 'cf_clearance' not in cookie_dict:
127
- logger.error("cf_clearance cookie not found")
128
- page.quit()
129
- return None
130
-
131
- cookie_str = '; '.join([f"{cookie['name']}={cookie['value']}" for cookie in cookies])
132
- global_data["cookie"] = cookie_str
133
- global_data["last_update"] = time.time()
134
-
135
- expires = min([cookie.get('expires', float('inf')) for cookie in cookies])
136
- if expires != float('inf'):
137
- global_data["cookie_expires"] = expires
138
- else:
139
- global_data["cookie_expires"] = time.time() + 3600
140
-
141
- logger.info("Successfully retrieved cookies")
142
- page.quit()
143
- return cookie_str
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
 
145
  except Exception as e:
146
  logger.error(f"Error fetching cookie: {str(e)}")
@@ -256,8 +327,12 @@ async def check_image_status(session: requests.Session, job_id: str, headers: di
256
  @app.get("/", response_class=HTMLResponse)
257
  async def health_check():
258
  """Health check endpoint"""
 
 
 
 
259
  status = {
260
- "status": "ok",
261
  "version": "1.0.0",
262
  "cookie_status": {
263
  "available": global_data["cookie"] is not None,
@@ -296,7 +371,7 @@ async def health_check():
296
  padding: 4px 8px;
297
  border-radius: 4px;
298
  font-weight: bold;
299
- background-color: #4CAF50;
300
  color: white;
301
  }}
302
  .info {{
@@ -319,7 +394,15 @@ async def health_check():
319
  border-radius: 4px;
320
  }}
321
  .cookie-status .available {{
322
- color: {"#4CAF50" if status["cookie_status"]["available"] else "#f44336"};
 
 
 
 
 
 
 
 
323
  }}
324
  </style>
325
  </head>
@@ -348,6 +431,10 @@ async def health_check():
348
  <span class="label">Expires:</span>
349
  <span class="value">{status["cookie_status"]["expires"] or "Unknown"}</span>
350
  </div>
 
 
 
 
351
  </div>
352
  </div>
353
  </body>
 
15
  import os
16
  import re
17
  import threading
 
 
18
  import logging
19
  from dotenv import load_dotenv
20
+ from playwright.sync_api import sync_playwright
21
 
22
  # 加载环境变量
23
  load_dotenv(override=True)
 
29
  )
30
  logger = logging.getLogger(__name__)
31
 
 
 
 
 
32
  # 修改全局数据存储
33
  global_data = {
34
  "cookie": None,
 
40
  @asynccontextmanager
41
  async def lifespan(app: FastAPI):
42
  # 启动时获取 cookie
43
+ logger.info("Starting FastAPI application, initializing cookie fetcher...")
44
+
45
+ # 创建并启动线程
46
+ cookie_thread = threading.Thread(target=get_cookie_with_retry)
47
+ cookie_thread.daemon = True # 设置为守护线程
48
+ cookie_thread.start()
49
+
50
+ logger.info("Cookie fetcher thread started")
51
  yield
52
+
53
  # 关闭时清理资源
54
+ logger.info("Shutting down FastAPI application")
55
  global_data["cookie"] = None
56
  global_data["cookies"] = None
57
  global_data["last_update"] = 0
58
 
59
+ def get_cookie_with_retry(max_retries=3, retry_delay=5):
60
+ """带重试机制的获取 cookie 函数"""
61
+ retries = 0
62
+ while retries < max_retries:
63
+ logger.info(f"Cookie fetching attempt {retries + 1}/{max_retries}")
64
+ cookie = get_cookie()
65
+ if cookie:
66
+ logger.info("Successfully retrieved cookie")
67
+ return cookie
68
+
69
+ retries += 1
70
+ if retries < max_retries:
71
+ logger.info(f"Retrying cookie fetch in {retry_delay} seconds...")
72
+ time.sleep(retry_delay)
73
+
74
+ logger.error(f"Failed to fetch cookie after {max_retries} attempts")
75
+ return None
76
+
77
  app = FastAPI(lifespan=lifespan)
78
  security = HTTPBearer()
79
 
 
86
  try:
87
  logger.info("Starting cookie retrieval process...")
88
 
89
+ with sync_playwright() as p:
90
+ try:
91
+ # 启动浏览器
92
+ logger.info("Launching browser...")
93
+ browser = p.chromium.launch(
94
+ headless=True,
95
+ args=[
96
+ '--no-sandbox',
97
+ '--disable-dev-shm-usage',
98
+ '--disable-gpu',
99
+ '--disable-software-rasterizer',
100
+ '--disable-extensions',
101
+ '--disable-setuid-sandbox',
102
+ '--no-first-run',
103
+ '--no-zygote',
104
+ '--single-process',
105
+ '--window-size=1920,1080',
106
+ '--disable-blink-features=AutomationControlled' # 禁用自动化控制检测
107
+ ]
108
+ )
109
+
110
+ logger.info("Browser launched successfully")
111
+
112
+ # 创建上下文,添加更多浏览器特征
113
+ logger.info("Creating browser context...")
114
+ context = browser.new_context(
115
+ viewport={'width': 1920, 'height': 1080},
116
+ user_agent='Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
117
+ locale='en-US',
118
+ timezone_id='America/New_York',
119
+ permissions=['geolocation'],
120
+ extra_http_headers={
121
+ 'Accept-Language': 'en-US,en;q=0.9',
122
+ 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
123
+ 'Sec-Ch-Ua': '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',
124
+ 'Sec-Ch-Ua-Mobile': '?0',
125
+ 'Sec-Ch-Ua-Platform': '"macOS"',
126
+ 'Sec-Fetch-Dest': 'document',
127
+ 'Sec-Fetch-Mode': 'navigate',
128
+ 'Sec-Fetch-Site': 'none',
129
+ 'Sec-Fetch-User': '?1',
130
+ 'Upgrade-Insecure-Requests': '1'
131
+ }
132
+ )
133
+
134
+ logger.info("Browser context created successfully")
135
+
136
+ # 创建页面
137
+ logger.info("Creating new page...")
138
+ page = context.new_page()
139
+ logger.info("Page created successfully")
140
+
141
+ # 设置页面超时
142
+ page.set_default_timeout(60000)
143
+
144
+ # 访问目标网站
145
+ logger.info("Navigating to target website...")
146
+ page.goto("https://chat.akash.network/", timeout=50000)
147
+
148
+ # 等待页面加载
149
+ logger.info("Waiting for page load...")
150
+ try:
151
+ # 首先等待 DOM 加载完成
152
+ page.wait_for_load_state("domcontentloaded", timeout=30000)
153
+ logger.info("DOM content loaded")
154
+
155
+ # 等待一段时间,让 Cloudflare 检查完成
156
+ logger.info("Waiting for Cloudflare check...")
157
+ time.sleep(5)
158
+
159
+ # 尝试点击页面,模拟用户行为
160
+ try:
161
+ page.mouse.move(100, 100)
162
+ page.mouse.click(100, 100)
163
+ logger.info("Simulated user interaction")
164
+ except Exception as e:
165
+ logger.warning(f"Failed to simulate user interaction: {e}")
166
+
167
+ # 再次等待一段时间
168
+ time.sleep(5)
169
+
170
+ except Exception as e:
171
+ logger.warning(f"Timeout waiting for load state: {e}")
172
+
173
+ # 获取 cookies
174
+ logger.info("Getting cookies...")
175
+ cookies = context.cookies()
176
+
177
+ if not cookies:
178
+ logger.error("No cookies found")
179
+ browser.close()
180
+ return None
181
+
182
+ # 检查是否有 cf_clearance cookie
183
+ cf_cookie = next((cookie for cookie in cookies if cookie['name'] == 'cf_clearance'), None)
184
+ if not cf_cookie:
185
+ logger.error("cf_clearance cookie not found")
186
+ browser.close()
187
+ return None
188
+
189
+ # 构建 cookie 字符串
190
+ cookie_str = '; '.join([f"{cookie['name']}={cookie['value']}" for cookie in cookies])
191
+ global_data["cookie"] = cookie_str
192
+ global_data["cookies"] = cookies # 保存完整的 cookies 列表
193
+ global_data["last_update"] = time.time()
194
+
195
+ # 查找 session_token cookie 的过期时间
196
+ session_cookie = next((cookie for cookie in cookies if cookie['name'] == 'session_token'), None)
197
+ if session_cookie and 'expires' in session_cookie and session_cookie['expires'] > 0:
198
+ global_data["cookie_expires"] = session_cookie['expires']
199
+ logger.info(f"Session token expires at: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(session_cookie['expires']))}")
200
+ else:
201
+ # 如果没有明确的过期时间,默认设置为1小时后过期
202
+ global_data["cookie_expires"] = time.time() + 3600
203
+ logger.info("No explicit expiration in session_token cookie, setting default 1 hour expiration")
204
+
205
+ logger.info("Successfully retrieved cookies")
206
+ browser.close()
207
+ return cookie_str
208
+
209
+ except Exception as e:
210
+ logger.error(f"Error in browser operations: {e}")
211
+ logger.error(f"Error type: {type(e)}")
212
+ import traceback
213
+ logger.error(f"Traceback: {traceback.format_exc()}")
214
+ return None
215
 
216
  except Exception as e:
217
  logger.error(f"Error fetching cookie: {str(e)}")
 
327
  @app.get("/", response_class=HTMLResponse)
328
  async def health_check():
329
  """Health check endpoint"""
330
+ # 检查 cookie 状态
331
+ cookie_status = "ok" if global_data["cookie"] is not None else "error"
332
+ cookie_status_color = "#4CAF50" if cookie_status == "ok" else "#f44336"
333
+
334
  status = {
335
+ "status": cookie_status,
336
  "version": "1.0.0",
337
  "cookie_status": {
338
  "available": global_data["cookie"] is not None,
 
371
  padding: 4px 8px;
372
  border-radius: 4px;
373
  font-weight: bold;
374
+ background-color: {cookie_status_color};
375
  color: white;
376
  }}
377
  .info {{
 
394
  border-radius: 4px;
395
  }}
396
  .cookie-status .available {{
397
+ color: {cookie_status_color};
398
+ }}
399
+ .error-message {{
400
+ color: #f44336;
401
+ margin-top: 10px;
402
+ padding: 10px;
403
+ background-color: #ffebee;
404
+ border-radius: 4px;
405
+ display: {"block" if cookie_status == "error" else "none"};
406
  }}
407
  </style>
408
  </head>
 
431
  <span class="label">Expires:</span>
432
  <span class="value">{status["cookie_status"]["expires"] or "Unknown"}</span>
433
  </div>
434
+
435
+ <div class="error-message">
436
+ Cookie retrieval failed. The service may not be fully functional.
437
+ </div>
438
  </div>
439
  </div>
440
  </body>