haha
This commit is contained in:
@@ -395,67 +395,123 @@ class BossRecruitHandler(BaseTaskHandler):
|
|||||||
)
|
)
|
||||||
return added, records
|
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:
|
def _greet_one_geek(self, page, container, item: dict) -> bool:
|
||||||
"""
|
"""
|
||||||
对单个牛人打招呼,完全对齐 1.py _greet_one_geek 逻辑:
|
对单个牛人打招呼,对齐 1.py _greet_one_geek 逻辑。
|
||||||
1. 找姓名 → scrollIntoView → 点击姓名
|
关键改进:使用 finally 确保失败时关闭所有面板/弹窗,
|
||||||
2. 获取 frame(1)(右侧面板)
|
防止 UI 残留导致下一个人卡死在循环中。
|
||||||
3. 点击"打招呼"
|
|
||||||
4. 点击"收藏"
|
|
||||||
5. 点击 3 次 btn-outline 按钮
|
|
||||||
6. 输入快速回复 → 发送
|
|
||||||
7. 关闭侧边栏 + 关闭弹窗
|
|
||||||
"""
|
"""
|
||||||
geek_name = str((item.get("geekCard") or {}).get("geekName", "")).strip()
|
geek_name = str((item.get("geekCard") or {}).get("geekName", "")).strip()
|
||||||
if not geek_name:
|
if not geek_name:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
panel_opened = False # 标记是否打开了右侧面板
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# 查找姓名元素(与 1.py 一致的双重查找)
|
# 查找姓名元素
|
||||||
name_ele = container.ele(f'x://span[contains(text(),"{geek_name}")]', timeout=5)
|
name_ele = container.ele(f'x://span[contains(text(),"{geek_name}")]', timeout=5)
|
||||||
if not name_ele:
|
if not name_ele:
|
||||||
name_ele = container.ele(f'x://span[text()="{geek_name}"]', timeout=2)
|
name_ele = container.ele(f'x://span[text()="{geek_name}"]', timeout=2)
|
||||||
if not name_ele:
|
if not name_ele:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# scrollIntoView + 点击(与 1.py 一致)
|
# scrollIntoView + 点击
|
||||||
name_ele.run_js("this.scrollIntoView()")
|
name_ele.run_js("this.scrollIntoView()")
|
||||||
name_ele.click()
|
name_ele.click()
|
||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
|
panel_opened = True
|
||||||
|
|
||||||
# 获取右侧面板(与 1.py 一致:page.get_frame(1))
|
# 获取右侧面板
|
||||||
panel = page.get_frame(1)
|
panel = page.get_frame(1)
|
||||||
time.sleep(random.uniform(0.5, 1.2))
|
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))
|
time.sleep(random.uniform(0.5, 1.2))
|
||||||
|
|
||||||
# 收藏(与 1.py 一致)
|
# 收藏(可选,失败不影响)
|
||||||
panel.ele('x://*[contains(text(),"收藏")]', timeout=2).click(by_js=True)
|
try:
|
||||||
time.sleep(random.uniform(0.5, 1.2))
|
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):
|
for _ in range(3):
|
||||||
panel.ele('x://*[@class="btn-v2 btn-outline-v2"]', timeout=2).click(by_js=True)
|
try:
|
||||||
time.sleep(random.uniform(0.5, 1.2))
|
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)
|
try:
|
||||||
page.ele('x://*[contains(text(),"发送")]', timeout=2).click()
|
input_box = page.ele('x://*[@data-placeholder="快速回复"]', timeout=2)
|
||||||
time.sleep(random.uniform(0.5, 1.2))
|
if input_box:
|
||||||
|
input_box.input(FAST_REPLY_TEXT)
|
||||||
# 关闭侧边栏(与 1.py 一致)
|
send_btn = page.ele('x://*[contains(text(),"发送")]', timeout=2)
|
||||||
page.ele('x://*[@class="iboss iboss-close"]').click()
|
if send_btn:
|
||||||
time.sleep(random.uniform(0.5, 1.2))
|
send_btn.click()
|
||||||
|
time.sleep(random.uniform(0.5, 1.2))
|
||||||
# 关闭弹窗(与 1.py 一致)
|
except Exception:
|
||||||
panel.ele('x://*[@class="boss-popup__close"]').click()
|
pass
|
||||||
time.sleep(random.uniform(0.5, 1.2))
|
|
||||||
|
|
||||||
|
# 关闭面板
|
||||||
|
self._close_all_panels(page)
|
||||||
|
panel_opened = False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
return False
|
return False
|
||||||
|
finally:
|
||||||
|
# 无论成功还是失败,都确保关闭所有面板
|
||||||
|
if panel_opened:
|
||||||
|
self._close_all_panels(page)
|
||||||
|
time.sleep(0.5)
|
||||||
|
|
||||||
# ────────────────────── 联系记录入库 ──────────────────────
|
# ────────────────────── 联系记录入库 ──────────────────────
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user