This commit is contained in:
ddrwode
2026-03-06 13:45:22 +08:00
parent 6c31e334a3
commit f98c848b60

View File

@@ -395,67 +395,123 @@ class BossRecruitHandler(BaseTaskHandler):
)
return added, records
@staticmethod
def _close_all_panels(page):
"""
强制关闭所有可能打开的面板和弹窗,确保 UI 恢复到干净状态。
每一步都独立 try/except不管成功或失败都继续。
"""
# 关闭侧边聊天面板
try:
close_side = page.ele('x://*[@class="iboss iboss-close"]', timeout=1)
if close_side:
close_side.click(by_js=True)
time.sleep(0.3)
except Exception:
pass
# 关闭 boss-popup 弹窗
try:
close_popup = page.ele('x://*[@class="boss-popup__close"]', timeout=1)
if close_popup:
close_popup.click(by_js=True)
time.sleep(0.3)
except Exception:
pass
# 兜底:尝试关闭所有可能的弹窗关闭按钮
for selector in [
'x://*[contains(@class,"close") and contains(@class,"popup")]',
'x://*[contains(@class,"dialog")]//button[contains(@class,"close")]',
]:
try:
btn = page.ele(selector, timeout=0.5)
if btn:
btn.click(by_js=True)
time.sleep(0.2)
except Exception:
pass
def _greet_one_geek(self, page, container, item: dict) -> bool:
"""
对单个牛人打招呼,完全对齐 1.py _greet_one_geek 逻辑
1. 找姓名 → scrollIntoView → 点击姓名
2. 获取 frame(1)(右侧面板)
3. 点击"打招呼"
4. 点击"收藏"
5. 点击 3 次 btn-outline 按钮
6. 输入快速回复 → 发送
7. 关闭侧边栏 + 关闭弹窗
对单个牛人打招呼,对齐 1.py _greet_one_geek 逻辑
关键改进:使用 finally 确保失败时关闭所有面板/弹窗,
防止 UI 残留导致下一个人卡死在循环中。
"""
geek_name = str((item.get("geekCard") or {}).get("geekName", "")).strip()
if not geek_name:
return False
panel_opened = False # 标记是否打开了右侧面板
try:
# 查找姓名元素(与 1.py 一致的双重查找)
# 查找姓名元素
name_ele = container.ele(f'x://span[contains(text(),"{geek_name}")]', timeout=5)
if not name_ele:
name_ele = container.ele(f'x://span[text()="{geek_name}"]', timeout=2)
if not name_ele:
return False
# scrollIntoView + 点击(与 1.py 一致)
# scrollIntoView + 点击
name_ele.run_js("this.scrollIntoView()")
name_ele.click()
time.sleep(3)
panel_opened = True
# 获取右侧面板(与 1.py 一致page.get_frame(1)
# 获取右侧面板
panel = page.get_frame(1)
time.sleep(random.uniform(0.5, 1.2))
# 打招呼(与 1.py 一致by_js=True
panel.ele('x://*[contains(text(),"打招呼")]', timeout=2).click(by_js=True)
# 打招呼
greet_btn = panel.ele('x://*[contains(text(),"打招呼")]', timeout=2)
if not greet_btn:
return False
greet_btn.click(by_js=True)
time.sleep(random.uniform(0.5, 1.2))
# 收藏(与 1.py 一致
panel.ele('x://*[contains(text(),"收藏")]', timeout=2).click(by_js=True)
time.sleep(random.uniform(0.5, 1.2))
# 收藏(可选,失败不影响
try:
collect_btn = panel.ele('x://*[contains(text(),"收藏")]', timeout=2)
if collect_btn:
collect_btn.click(by_js=True)
time.sleep(random.uniform(0.5, 1.2))
except Exception:
pass
# 点击 3 次 btn-outline 按钮(与 1.py 一致
# 点击 btn-outline 按钮(可选,失败不影响
for _ in range(3):
panel.ele('x://*[@class="btn-v2 btn-outline-v2"]', timeout=2).click(by_js=True)
time.sleep(random.uniform(0.5, 1.2))
try:
extra_btn = panel.ele('x://*[@class="btn-v2 btn-outline-v2"]', timeout=1)
if extra_btn:
extra_btn.click(by_js=True)
time.sleep(random.uniform(0.5, 1.2))
except Exception:
break
# 快速回复(与 1.py 一致
page.ele('x://*[@data-placeholder="快速回复"]', timeout=2).input(FAST_REPLY_TEXT)
page.ele('x://*[contains(text(),"发送")]', timeout=2).click()
time.sleep(random.uniform(0.5, 1.2))
# 关闭侧边栏(与 1.py 一致)
page.ele('x://*[@class="iboss iboss-close"]').click()
time.sleep(random.uniform(0.5, 1.2))
# 关闭弹窗(与 1.py 一致)
panel.ele('x://*[@class="boss-popup__close"]').click()
time.sleep(random.uniform(0.5, 1.2))
# 快速回复(可选,失败不影响
try:
input_box = page.ele('x://*[@data-placeholder="快速回复"]', timeout=2)
if input_box:
input_box.input(FAST_REPLY_TEXT)
send_btn = page.ele('x://*[contains(text(),"发送")]', timeout=2)
if send_btn:
send_btn.click()
time.sleep(random.uniform(0.5, 1.2))
except Exception:
pass
# 关闭面板
self._close_all_panels(page)
panel_opened = False
return True
except Exception:
return False
finally:
# 无论成功还是失败,都确保关闭所有面板
if panel_opened:
self._close_all_panels(page)
time.sleep(0.5)
# ────────────────────── 联系记录入库 ──────────────────────