diff --git a/inbound_verify/sites/yunda.py b/inbound_verify/sites/yunda.py index 1e912d0..7c961da 100644 --- a/inbound_verify/sites/yunda.py +++ b/inbound_verify/sites/yunda.py @@ -172,6 +172,37 @@ def _resolve_export_frame(ws_frame): return ws_frame.frame_locator('iframe[name="myFrame"]') +def _resolve_business_frame(page, probe_selector, label): + """定位当前「可见」的业务 iframe(返回 Frame,用法与 FrameLocator 兼容)。 + + 韵达门户每次切换菜单都会保留历史隐藏 iframe(display:none),因此不能按 + `section iframe` 全量匹配(会命中多个,strict mode 报错)。这里遍历 + page.frames,取「可见」且「包含指定控件」的 frame;probe_selector 需是 + 目标页面独有的控件:应到=#startTime,实到=#startDate,导出服务=.datagrid-view2。 + """ + print(f">> 正在定位业务 iframe({label})...") + deadline = time.monotonic() + 20 + last_err = None + while time.monotonic() < deadline: + for frame in page.frames: + if frame is page.main_frame: + continue + try: + if not frame.frame_element().is_visible(): + continue + except Exception as e: + last_err = e + continue + try: + if frame.locator(probe_selector).count() > 0: + print(f" ✅ 已定位业务 iframe({label}): {frame.url[:100]}") + return frame + except Exception as e: + last_err = e + page.wait_for_timeout(500) + raise RuntimeError(f"未定位到可见业务 iframe({label}): {last_err}") + + def yunda_login(page): """韵达自动登录:未登录则填充表单并提交,已登录则跳过。""" print(">> 正在检查韵达登录状态...") @@ -270,7 +301,7 @@ def yunda_expected_download_impl(page, force=False, date=None): yunda_smart_menu_click(page, ["运营管理", "进站管理", "进站交接单查询"]) print(">> 正在定位【进站交接单查询】iframe...") - ws_frame = page.frame_locator("section iframe") + ws_frame = _resolve_business_frame(page, "#startTime", "进站交接单查询") ws_frame.locator("#startTime").wait_for(state="attached", timeout=15000) print("✅ 进站交接单查询页面就绪") @@ -527,7 +558,7 @@ def yunda_actual_download_impl(page, date=None): yunda_smart_menu_click(page, ["报表管理", "扫描记录查询"]) print(">> 正在定位【扫描记录查询】iframe...") - ws_frame = page.frame_locator("section iframe") + ws_frame = _resolve_business_frame(page, "#startDate", "扫描记录查询") ws_frame.locator( ".no-records-found", has_text="没有找到匹配的记录" @@ -714,7 +745,7 @@ def _yunda_poll_and_download_tasks(page, export_times, download_dir, final_filen print("\n>> 正在前往【导出服务】界面...") yunda_smart_menu_click(page, ["基础数据", "导出服务"]) - export_ws_frame = page.frame_locator("section iframe") + export_ws_frame = _resolve_business_frame(page, ".datagrid-view2", "导出服务") export_ws_frame.get_by_role("cell", name="模块名称", exact=True).wait_for( state="visible", timeout=15000