From 54934cadd5e253f51d81e17f7c95b843127d16cb Mon Sep 17 00:00:00 2001 From: ddrwode <34234@3来 34> Date: Fri, 6 Mar 2026 14:06:33 +0800 Subject: [PATCH] haha --- worker/tasks/boss_recruit.py | 122 +++++++---------------------------- 1 file changed, 25 insertions(+), 97 deletions(-) diff --git a/worker/tasks/boss_recruit.py b/worker/tasks/boss_recruit.py index b53e89c..c92a10a 100644 --- a/worker/tasks/boss_recruit.py +++ b/worker/tasks/boss_recruit.py @@ -467,11 +467,9 @@ class BossRecruitHandler(BaseTaskHandler): def _greet_one_geek(self, page, container, item: dict) -> bool: """ - 对单个牛人打招呼。 - 关键:点击姓名后,BOSS 会动态加载一个新 iframe(简历详情面板), - "打招呼"按钮在这个面板 frame 中。 - 不能搜索所有 frame(因为 recommendFrame 中也有打招呼按钮), - 必须精确定位到详情面板 frame。 + 对单个牛人打招呼 —— 与 1.py _greet_one_geek 完全一致的逻辑。 + 使用 page.get_frame(1) 获取详情面板,所有元素查找语法与 1.py 相同。 + 仅增加 try/finally 防止异常时 UI 卡死。 """ geek_name = str((item.get("geekCard") or {}).get("geekName", "")).strip() if not geek_name: @@ -480,67 +478,46 @@ class BossRecruitHandler(BaseTaskHandler): panel_opened = False try: - # 查找姓名元素 + # 与 1.py 一致:查找姓名 → scrollIntoView → 点击 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 + 点击 name_ele.run_js("this.scrollIntoView()") name_ele.click() time.sleep(3) panel_opened = True - # 获取简历详情面板 frame(非 recommendFrame 的那个 iframe) - panel = self._get_detail_panel_frame(page) - if not panel: - return False + # 与 1.py 一致:a = page.get_frame(1) + a = page.get_frame(1) time.sleep(random.uniform(0.5, 1.2)) - # 打招呼 - greet_btn = panel.ele('x://*[contains(text(),"打招呼")]', timeout=3) - if not greet_btn: - return False - greet_btn.click(by_js=True) + # 与 1.py 一致:打招呼 + a.ele(f'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 + # 与 1.py 一致:收藏 + a.ele(f'x://*[contains(text(),"收藏")]', timeout=2).click(by_js=True) + time.sleep(random.uniform(0.5, 1.2)) - # 点击 btn-outline 按钮(可选) - for _ in range(3): - 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)) - else: - break - except Exception: - break + # 与 1.py 一致:btn-outline × 3 + for i in range(3): + a.ele(f'x://*[@class="btn-v2 btn-outline-v2"]', timeout=2).click(by_js=True) + 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 + # 与 1.py 一致:快速回复 + 发送 + page.ele(f'x://*[@data-placeholder="快速回复"]', timeout=2).input(FAST_REPLY_TEXT) + page.ele(f'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)) + a.ele('x://*[@class="boss-popup__close"]').click() + time.sleep(random.uniform(0.5, 1.2)) - # 关闭面板 - self._close_all_panels(page) panel_opened = False return True @@ -551,55 +528,6 @@ class BossRecruitHandler(BaseTaskHandler): self._close_all_panels(page) time.sleep(0.5) - @staticmethod - def _get_detail_panel_frame(page): - """ - 获取简历详情面板 frame。 - - 页面结构: - - frame 0: recommendFrame(推荐牛人列表,name="recommendFrame") - - frame 1: 简历详情面板(点击牛人后动态加载的 iframe,无固定 name) - - 由于多次交互后 frame 索引可能变化,不能用固定索引。 - 策略:遍历所有 frame,排除 name="recommendFrame" 的,返回另一个。 - """ - try: - frames = page.get_frames() - except Exception: - return None - - if not frames: - return None - - # 只有一个 frame 时,它就是 recommendFrame,没有详情面板 - if len(frames) <= 1: - # 仍然尝试 get_frame(1)(可能 DrissionPage 有隐式 frame) - try: - return page.get_frame(1) - except Exception: - return None - - # 多个 frame 时,找到不是 recommendFrame 的那个 - for i in range(len(frames) - 1, -1, -1): # 倒序,最新加载的通常在后面 - try: - frame = page.get_frame(i) - # 检查 frame 的 name 属性 - frame_ele = getattr(frame, 'frame_ele', None) - if frame_ele: - name = frame_ele.attr('name') or '' - if name == 'recommendFrame': - continue - # 不是 recommendFrame 的 frame 就是详情面板 - return frame - except Exception: - continue - - # 兜底:如果上面的方法都失败,尝试直接 get_frame(1) - try: - return page.get_frame(1) - except Exception: - return None - # ────────────────────── 联系记录入库 ────────────────────── def _save_new_greet_contacts(self, *, records: List[dict], worker_id: str, account_name: str) -> int: