StarrySkyWorld commited on
Commit
78cbf44
·
verified ·
1 Parent(s): 5d9e29c

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +142 -135
main.py CHANGED
@@ -85,57 +85,106 @@ async def auto_click_task():
85
 
86
  try:
87
  for text in click_buttons:
88
- # 各种选择器
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  selectors = [
 
 
 
 
 
 
 
 
 
 
90
  # 标准按钮
91
  f'button:has-text("{text}")',
92
- f'a:has-text("{text}")',
93
  f'[role="button"]:has-text("{text}")',
94
- # Material/Angular 组件
95
- f'mat-button:has-text("{text}")',
96
- f'mat-dialog-actions button:has-text("{text}")',
97
- f'.mat-mdc-dialog-actions button:has-text("{text}")',
98
- f'.cdk-overlay-container button:has-text("{text}")',
99
- f'.mdc-dialog button:has-text("{text}")',
100
- f'.mdc-dialog__actions button:has-text("{text}")',
 
101
  # 通用弹窗
102
  f'[class*="dialog"] button:has-text("{text}")',
103
  f'[class*="modal"] button:has-text("{text}")',
104
- f'[class*="popup"] button:has-text("{text}")',
105
- f'[class*="overlay"] button:has-text("{text}")',
106
- f'[class*="toast"] button:has-text("{text}")',
107
- f'[class*="snack"] button:has-text("{text}")',
108
- f'[class*="banner"] button:has-text("{text}")',
109
- f'[class*="consent"] button:has-text("{text}")',
110
- # 文本匹配
111
- f'span:text-is("{text}")',
112
- f'div:text-is("{text}")',
113
  ]
114
 
115
- # 主页面查找
116
  for selector in selectors:
117
  try:
118
  element = page.locator(selector).first
119
  if await element.is_visible(timeout=100):
120
  await element.click(timeout=2000)
121
- print(f'[AutoClick] Clicked "{text}" button in main page')
122
  return
123
  except:
124
  continue
125
 
126
- # 所有 iframe 中查找
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
  for frame in page.frames:
128
  if frame == page.main_frame:
129
  continue
130
- for selector in selectors[:5]: # iframe中只用基础选择器
131
- try:
132
- element = frame.locator(selector).first
133
- if await element.is_visible(timeout=100):
134
- await element.click(timeout=2000)
135
- print(f'[AutoClick] Clicked "{text}" button in iframe')
136
- return
137
- except:
138
- continue
139
 
140
  except Exception as e:
141
  pass
@@ -293,38 +342,38 @@ async def manual_click(text: str):
293
  return {"status": "error", "message": "Browser not initialized"}
294
 
295
  try:
296
- selectors = [
297
- f'button:has-text("{text}")',
298
- f'a:has-text("{text}")',
299
- f'[role="button"]:has-text("{text}")',
300
- f'.cdk-overlay-container button:has-text("{text}")',
301
- f'[class*="dialog"] button:has-text("{text}")',
302
- f'div:text-is("{text}")',
303
- f'span:text-is("{text}")',
304
- ]
305
-
306
- # 主页面
307
- for selector in selectors:
308
- try:
309
- element = page.locator(selector).first
310
- if await element.is_visible(timeout=1000):
311
- await element.click(timeout=3000)
312
- return {"status": "success", "message": f'Clicked "{text}" in main page'}
313
- except:
314
- continue
315
 
316
- # iframe
317
- for frame in page.frames:
318
- if frame == page.main_frame:
319
- continue
320
- for selector in selectors[:3]:
321
- try:
322
- element = frame.locator(selector).first
323
- if await element.is_visible(timeout=500):
324
- await element.click(timeout=3000)
325
- return {"status": "success", "message": f'Clicked "{text}" in iframe'}
326
- except:
327
- continue
 
 
 
 
 
 
 
 
 
 
 
328
 
329
  return {"status": "error", "message": f'Button with text "{text}" not found'}
330
  except Exception as e:
@@ -338,79 +387,38 @@ async def debug_buttons():
338
  return {"status": "error", "message": "Browser not initialized"}
339
 
340
  try:
341
- buttons = []
342
-
343
- # 主页面按钮
344
- button_elements = await page.locator('button, [role="button"], a[class*="button"], a[class*="btn"]').all()
345
- for i, btn in enumerate(button_elements[:30]):
346
- try:
347
- text = await btn.inner_text(timeout=500)
348
- visible = await btn.is_visible(timeout=500)
349
- buttons.append({
350
- "index": i,
351
- "text": text.strip()[:50],
352
- "visible": visible,
353
- "frame": "main"
354
- })
355
- except:
356
- continue
357
-
358
- # CDK Overlay (Angular Material 弹窗)
359
- try:
360
- overlay_buttons = await page.locator('.cdk-overlay-container button, .cdk-overlay-container [role="button"]').all()
361
- for i, btn in enumerate(overlay_buttons[:10]):
362
- try:
363
- text = await btn.inner_text(timeout=500)
364
- visible = await btn.is_visible(timeout=500)
365
- buttons.append({
366
- "index": i,
367
- "text": text.strip()[:50],
368
- "visible": visible,
369
- "frame": "cdk-overlay"
370
- })
371
- except:
372
- continue
373
- except:
374
- pass
375
-
376
- # iframe 中的按钮
377
- for frame_idx, frame in enumerate(page.frames):
378
- if frame == page.main_frame:
379
- continue
380
- try:
381
- frame_buttons = await frame.locator('button, [role="button"]').all()
382
- for i, btn in enumerate(frame_buttons[:10]):
383
- try:
384
- text = await btn.inner_text(timeout=500)
385
- visible = await btn.is_visible(timeout=500)
386
- buttons.append({
387
- "index": i,
388
- "text": text.strip()[:50],
389
- "visible": visible,
390
- "frame": f"iframe-{frame_idx}"
391
- })
392
- except:
393
- continue
394
- except:
395
- continue
396
 
397
  return {"status": "success", "count": len(buttons), "buttons": buttons}
398
  except Exception as e:
399
  return {"status": "error", "message": str(e)}
400
 
401
- @app.get("/debug/html")
402
- async def debug_html(selector: str = "body"):
403
- """调试:获取元素HTML"""
404
- global page
405
- if not page:
406
- return {"status": "error", "message": "Browser not initialized"}
407
-
408
- try:
409
- html = await page.locator(selector).first.inner_html(timeout=5000)
410
- return {"status": "success", "html": html[:5000]}
411
- except Exception as e:
412
- return {"status": "error", "message": str(e)}
413
-
414
  @app.get("/debug/overlay")
415
  async def debug_overlay():
416
  """调试:检查 CDK Overlay 弹窗内容"""
@@ -419,12 +427,11 @@ async def debug_overlay():
419
  return {"status": "error", "message": "Browser not initialized"}
420
 
421
  try:
422
- overlay = page.locator('.cdk-overlay-container')
423
- if await overlay.count() > 0:
424
- html = await overlay.inner_html(timeout=5000)
425
- return {"status": "success", "html": html[:5000]}
426
- else:
427
- return {"status": "success", "html": "No overlay found"}
428
  except Exception as e:
429
  return {"status": "error", "message": str(e)}
430
 
 
85
 
86
  try:
87
  for text in click_buttons:
88
+ # 方法1: 使用 getByRole 精确匹配按钮
89
+ try:
90
+ btn = page.get_by_role("button", name=text, exact=False)
91
+ if await btn.count() > 0 and await btn.first.is_visible(timeout=100):
92
+ await btn.first.click(timeout=2000)
93
+ print(f'[AutoClick] Clicked "{text}" via getByRole')
94
+ return
95
+ except:
96
+ pass
97
+
98
+ # 方法2: 使用 getByText
99
+ try:
100
+ btn = page.get_by_text(text, exact=True)
101
+ if await btn.count() > 0 and await btn.first.is_visible(timeout=100):
102
+ await btn.first.click(timeout=2000)
103
+ print(f'[AutoClick] Clicked "{text}" via getByText')
104
+ return
105
+ except:
106
+ pass
107
+
108
+ # 方法3: 各种 CSS 选择器
109
  selectors = [
110
+ # CDK Overlay (Angular Material Dialog)
111
+ f'.cdk-overlay-container button:has-text("{text}")',
112
+ f'.cdk-overlay-container [mat-button]:has-text("{text}")',
113
+ f'.cdk-overlay-container [mat-raised-button]:has-text("{text}")',
114
+ f'.cdk-overlay-container [mat-flat-button]:has-text("{text}")',
115
+ f'.cdk-overlay-container mat-dialog-actions button:has-text("{text}")',
116
+ f'.cdk-overlay-container .mat-mdc-dialog-actions button:has-text("{text}")',
117
+ f'.cdk-overlay-container .mdc-dialog__actions button:has-text("{text}")',
118
+ f'.cdk-overlay-pane button:has-text("{text}")',
119
+ f'mat-dialog-container button:has-text("{text}")',
120
  # 标准按钮
121
  f'button:has-text("{text}")',
122
+ f'button:text-is("{text}")',
123
  f'[role="button"]:has-text("{text}")',
124
+ f'a:has-text("{text}")',
125
+ # Material 按钮
126
+ f'.mat-button:has-text("{text}")',
127
+ f'.mat-mdc-button:has-text("{text}")',
128
+ f'.mdc-button:has-text("{text}")',
129
+ # ms-button (Google 自定义)
130
+ f'[ms-button]:has-text("{text}")',
131
+ f'.ms-button:has-text("{text}")',
132
  # 通用弹窗
133
  f'[class*="dialog"] button:has-text("{text}")',
134
  f'[class*="modal"] button:has-text("{text}")',
 
 
 
 
 
 
 
 
 
135
  ]
136
 
 
137
  for selector in selectors:
138
  try:
139
  element = page.locator(selector).first
140
  if await element.is_visible(timeout=100):
141
  await element.click(timeout=2000)
142
+ print(f'[AutoClick] Clicked "{text}" via selector: {selector}')
143
  return
144
  except:
145
  continue
146
 
147
+ # 方法4: JavaScript 点击
148
+ try:
149
+ clicked = await page.evaluate(f'''() => {{
150
+ const buttons = document.querySelectorAll('button, [role="button"], [mat-button], [ms-button]');
151
+ for (const btn of buttons) {{
152
+ if (btn.textContent.trim().toLowerCase().includes("{text.lower()}")) {{
153
+ btn.click();
154
+ return true;
155
+ }}
156
+ }}
157
+ // 检查 CDK overlay
158
+ const overlay = document.querySelector('.cdk-overlay-container');
159
+ if (overlay) {{
160
+ const overlayButtons = overlay.querySelectorAll('button, [role="button"]');
161
+ for (const btn of overlayButtons) {{
162
+ if (btn.textContent.trim().toLowerCase().includes("{text.lower()}")) {{
163
+ btn.click();
164
+ return true;
165
+ }}
166
+ }}
167
+ }}
168
+ return false;
169
+ }}''')
170
+ if clicked:
171
+ print(f'[AutoClick] Clicked "{text}" via JavaScript')
172
+ return
173
+ except:
174
+ pass
175
+
176
+ # 方法5: 在 iframe 中查找
177
  for frame in page.frames:
178
  if frame == page.main_frame:
179
  continue
180
+ try:
181
+ btn = frame.get_by_role("button", name=text, exact=False)
182
+ if await btn.count() > 0 and await btn.first.is_visible(timeout=100):
183
+ await btn.first.click(timeout=2000)
184
+ print(f'[AutoClick] Clicked "{text}" in iframe')
185
+ return
186
+ except:
187
+ continue
 
188
 
189
  except Exception as e:
190
  pass
 
342
  return {"status": "error", "message": "Browser not initialized"}
343
 
344
  try:
345
+ # 方法1: getByRole
346
+ try:
347
+ btn = page.get_by_role("button", name=text, exact=False)
348
+ if await btn.count() > 0 and await btn.first.is_visible(timeout=1000):
349
+ await btn.first.click(timeout=3000)
350
+ return {"status": "success", "message": f'Clicked "{text}" via getByRole'}
351
+ except:
352
+ pass
 
 
 
 
 
 
 
 
 
 
 
353
 
354
+ # 方法2: JavaScript
355
+ clicked = await page.evaluate(f'''() => {{
356
+ const buttons = document.querySelectorAll('button, [role="button"], [mat-button], [ms-button]');
357
+ for (const btn of buttons) {{
358
+ if (btn.textContent.trim().toLowerCase().includes("{text.lower()}")) {{
359
+ btn.click();
360
+ return true;
361
+ }}
362
+ }}
363
+ const overlay = document.querySelector('.cdk-overlay-container');
364
+ if (overlay) {{
365
+ const overlayButtons = overlay.querySelectorAll('button, [role="button"]');
366
+ for (const btn of overlayButtons) {{
367
+ if (btn.textContent.trim().toLowerCase().includes("{text.lower()}")) {{
368
+ btn.click();
369
+ return true;
370
+ }}
371
+ }}
372
+ }}
373
+ return false;
374
+ }}''')
375
+ if clicked:
376
+ return {"status": "success", "message": f'Clicked "{text}" via JavaScript'}
377
 
378
  return {"status": "error", "message": f'Button with text "{text}" not found'}
379
  except Exception as e:
 
387
  return {"status": "error", "message": "Browser not initialized"}
388
 
389
  try:
390
+ # 使用 JavaScript 获取所有按钮,包括 overlay 中的
391
+ buttons = await page.evaluate('''() => {
392
+ const results = [];
393
+ const allButtons = document.querySelectorAll('button, [role="button"], [mat-button], [ms-button]');
394
+ allButtons.forEach((btn, i) => {
395
+ results.push({
396
+ index: i,
397
+ text: btn.textContent.trim().substring(0, 50),
398
+ visible: btn.offsetParent !== null,
399
+ frame: 'main'
400
+ });
401
+ });
402
+ // CDK Overlay
403
+ const overlay = document.querySelector('.cdk-overlay-container');
404
+ if (overlay) {
405
+ const overlayButtons = overlay.querySelectorAll('button, [role="button"]');
406
+ overlayButtons.forEach((btn, i) => {
407
+ results.push({
408
+ index: i,
409
+ text: btn.textContent.trim().substring(0, 50),
410
+ visible: btn.offsetParent !== null || getComputedStyle(btn).display !== 'none',
411
+ frame: 'cdk-overlay'
412
+ });
413
+ });
414
+ }
415
+ return results;
416
+ }''')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
417
 
418
  return {"status": "success", "count": len(buttons), "buttons": buttons}
419
  except Exception as e:
420
  return {"status": "error", "message": str(e)}
421
 
 
 
 
 
 
 
 
 
 
 
 
 
 
422
  @app.get("/debug/overlay")
423
  async def debug_overlay():
424
  """调试:检查 CDK Overlay 弹窗内容"""
 
427
  return {"status": "error", "message": "Browser not initialized"}
428
 
429
  try:
430
+ html = await page.evaluate('''() => {
431
+ const overlay = document.querySelector('.cdk-overlay-container');
432
+ return overlay ? overlay.innerHTML : 'No overlay found';
433
+ }''')
434
+ return {"status": "success", "html": html[:8000]}
 
435
  except Exception as e:
436
  return {"status": "error", "message": str(e)}
437