Spaces:
Paused
Paused
Update main.py
Browse files
main.py
CHANGED
|
@@ -80,24 +80,58 @@ async def auto_click_task():
|
|
| 80 |
if not page:
|
| 81 |
return
|
| 82 |
|
|
|
|
|
|
|
|
|
|
| 83 |
try:
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 89 |
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
await element.click(timeout=1000)
|
| 95 |
-
print(f'[AutoClick] Clicked "Got it" button')
|
| 96 |
-
return
|
| 97 |
-
except:
|
| 98 |
continue
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 99 |
|
| 100 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 101 |
pass
|
| 102 |
|
| 103 |
async def init_browser():
|
|
@@ -244,6 +278,113 @@ async def navigate_to(url: str):
|
|
| 244 |
except Exception as e:
|
| 245 |
return {"status": "warning", "message": f"Navigation completed with issue: {e}"}
|
| 246 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 247 |
@app.get("/health")
|
| 248 |
async def health_check():
|
| 249 |
"""健康检查"""
|
|
|
|
| 80 |
if not page:
|
| 81 |
return
|
| 82 |
|
| 83 |
+
# 匹配多种大小写形式
|
| 84 |
+
text_patterns = ["Got it", "GOT IT", "Got It", "got it", "GOTIT", "Gotit"]
|
| 85 |
+
|
| 86 |
try:
|
| 87 |
+
# 1. 先在主页面查找
|
| 88 |
+
for text in text_patterns:
|
| 89 |
+
selectors = [
|
| 90 |
+
f'button:has-text("{text}")',
|
| 91 |
+
f'a:has-text("{text}")',
|
| 92 |
+
f'[role="button"]:has-text("{text}")',
|
| 93 |
+
f'div:has-text("{text}"):not(:has(div:has-text("{text}")))', # 最内层div
|
| 94 |
+
f'span:has-text("{text}")',
|
| 95 |
+
f'mat-button:has-text("{text}")', # Angular Material
|
| 96 |
+
f'[data-mdc-dialog-action]:has-text("{text}")', # Material Dialog
|
| 97 |
+
]
|
| 98 |
+
|
| 99 |
+
for selector in selectors:
|
| 100 |
+
try:
|
| 101 |
+
element = page.locator(selector).first
|
| 102 |
+
if await element.is_visible(timeout=100):
|
| 103 |
+
await element.click(timeout=2000)
|
| 104 |
+
print(f'[AutoClick] Clicked "{text}" button in main page')
|
| 105 |
+
return
|
| 106 |
+
except:
|
| 107 |
+
continue
|
| 108 |
|
| 109 |
+
# 2. 在所有 iframe 中查找
|
| 110 |
+
frames = page.frames
|
| 111 |
+
for frame in frames:
|
| 112 |
+
if frame == page.main_frame:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 113 |
continue
|
| 114 |
+
|
| 115 |
+
for text in text_patterns:
|
| 116 |
+
selectors = [
|
| 117 |
+
f'button:has-text("{text}")',
|
| 118 |
+
f'a:has-text("{text}")',
|
| 119 |
+
f'[role="button"]:has-text("{text}")',
|
| 120 |
+
f'div:has-text("{text}"):not(:has(div:has-text("{text}")))',
|
| 121 |
+
f'span:has-text("{text}")',
|
| 122 |
+
]
|
| 123 |
|
| 124 |
+
for selector in selectors:
|
| 125 |
+
try:
|
| 126 |
+
element = frame.locator(selector).first
|
| 127 |
+
if await element.is_visible(timeout=100):
|
| 128 |
+
await element.click(timeout=2000)
|
| 129 |
+
print(f'[AutoClick] Clicked "{text}" button in iframe')
|
| 130 |
+
return
|
| 131 |
+
except:
|
| 132 |
+
continue
|
| 133 |
+
|
| 134 |
+
except Exception as e:
|
| 135 |
pass
|
| 136 |
|
| 137 |
async def init_browser():
|
|
|
|
| 278 |
except Exception as e:
|
| 279 |
return {"status": "warning", "message": f"Navigation completed with issue: {e}"}
|
| 280 |
|
| 281 |
+
@app.get("/click")
|
| 282 |
+
async def manual_click(text: str):
|
| 283 |
+
"""手动点击包含指定文本的按钮"""
|
| 284 |
+
global page
|
| 285 |
+
if not page:
|
| 286 |
+
return {"status": "error", "message": "Browser not initialized"}
|
| 287 |
+
|
| 288 |
+
try:
|
| 289 |
+
selectors = [
|
| 290 |
+
f'button:has-text("{text}")',
|
| 291 |
+
f'a:has-text("{text}")',
|
| 292 |
+
f'[role="button"]:has-text("{text}")',
|
| 293 |
+
f'div:has-text("{text}")',
|
| 294 |
+
f'span:has-text("{text}")',
|
| 295 |
+
]
|
| 296 |
+
|
| 297 |
+
# 主页面
|
| 298 |
+
for selector in selectors:
|
| 299 |
+
try:
|
| 300 |
+
element = page.locator(selector).first
|
| 301 |
+
if await element.is_visible(timeout=500):
|
| 302 |
+
await element.click(timeout=3000)
|
| 303 |
+
return {"status": "success", "message": f'Clicked "{text}" in main page'}
|
| 304 |
+
except:
|
| 305 |
+
continue
|
| 306 |
+
|
| 307 |
+
# iframe
|
| 308 |
+
for frame in page.frames:
|
| 309 |
+
if frame == page.main_frame:
|
| 310 |
+
continue
|
| 311 |
+
for selector in selectors:
|
| 312 |
+
try:
|
| 313 |
+
element = frame.locator(selector).first
|
| 314 |
+
if await element.is_visible(timeout=500):
|
| 315 |
+
await element.click(timeout=3000)
|
| 316 |
+
return {"status": "success", "message": f'Clicked "{text}" in iframe'}
|
| 317 |
+
except:
|
| 318 |
+
continue
|
| 319 |
+
|
| 320 |
+
return {"status": "error", "message": f'Button with text "{text}" not found'}
|
| 321 |
+
except Exception as e:
|
| 322 |
+
return {"status": "error", "message": str(e)}
|
| 323 |
+
|
| 324 |
+
@app.get("/debug/buttons")
|
| 325 |
+
async def debug_buttons():
|
| 326 |
+
"""调试:列出页面上所有按钮"""
|
| 327 |
+
global page
|
| 328 |
+
if not page:
|
| 329 |
+
return {"status": "error", "message": "Browser not initialized"}
|
| 330 |
+
|
| 331 |
+
try:
|
| 332 |
+
buttons = []
|
| 333 |
+
|
| 334 |
+
# 主页面按钮
|
| 335 |
+
button_elements = await page.locator('button, [role="button"], a[class*="button"], a[class*="btn"]').all()
|
| 336 |
+
for i, btn in enumerate(button_elements[:20]): # 最多20个
|
| 337 |
+
try:
|
| 338 |
+
text = await btn.inner_text(timeout=500)
|
| 339 |
+
visible = await btn.is_visible(timeout=500)
|
| 340 |
+
buttons.append({
|
| 341 |
+
"index": i,
|
| 342 |
+
"text": text.strip()[:50],
|
| 343 |
+
"visible": visible,
|
| 344 |
+
"frame": "main"
|
| 345 |
+
})
|
| 346 |
+
except:
|
| 347 |
+
continue
|
| 348 |
+
|
| 349 |
+
# iframe 中的按钮
|
| 350 |
+
for frame_idx, frame in enumerate(page.frames):
|
| 351 |
+
if frame == page.main_frame:
|
| 352 |
+
continue
|
| 353 |
+
try:
|
| 354 |
+
frame_buttons = await frame.locator('button, [role="button"]').all()
|
| 355 |
+
for i, btn in enumerate(frame_buttons[:10]):
|
| 356 |
+
try:
|
| 357 |
+
text = await btn.inner_text(timeout=500)
|
| 358 |
+
visible = await btn.is_visible(timeout=500)
|
| 359 |
+
buttons.append({
|
| 360 |
+
"index": i,
|
| 361 |
+
"text": text.strip()[:50],
|
| 362 |
+
"visible": visible,
|
| 363 |
+
"frame": f"iframe-{frame_idx}"
|
| 364 |
+
})
|
| 365 |
+
except:
|
| 366 |
+
continue
|
| 367 |
+
except:
|
| 368 |
+
continue
|
| 369 |
+
|
| 370 |
+
return {"status": "success", "count": len(buttons), "buttons": buttons}
|
| 371 |
+
except Exception as e:
|
| 372 |
+
return {"status": "error", "message": str(e)}
|
| 373 |
+
|
| 374 |
+
@app.get("/debug/html")
|
| 375 |
+
async def debug_html(selector: str = "body"):
|
| 376 |
+
"""调试:获取元素HTML"""
|
| 377 |
+
global page
|
| 378 |
+
if not page:
|
| 379 |
+
return {"status": "error", "message": "Browser not initialized"}
|
| 380 |
+
|
| 381 |
+
try:
|
| 382 |
+
html = await page.locator(selector).first.inner_html(timeout=5000)
|
| 383 |
+
# 截取部分
|
| 384 |
+
return {"status": "success", "html": html[:5000]}
|
| 385 |
+
except Exception as e:
|
| 386 |
+
return {"status": "error", "message": str(e)}
|
| 387 |
+
|
| 388 |
@app.get("/health")
|
| 389 |
async def health_check():
|
| 390 |
"""健康检查"""
|