From ee559786e77d4d1f18b057c643e223100d28173b Mon Sep 17 00:00:00 2001 From: butubb <1422726308@qq.com> Date: Sun, 13 Sep 2026 21:01:53 +0800 Subject: [PATCH] =?UTF-8?q?docs(research):=20=E8=A1=A5=E3=80=8C=E6=8A=93?= =?UTF-8?q?=E5=8F=96=E5=BC=B9=E7=AA=97=E8=80=81=E6=98=AF=E9=94=99=E4=BD=8D?= =?UTF-8?q?=E3=80=8D=E7=9A=84=E7=9C=9F=E5=9B=A0=E2=80=94=E2=80=94=E6=88=AA?= =?UTF-8?q?=E5=9B=BE=E4=B8=8E=E5=85=83=E7=B4=A0=E6=A0=91=E4=B8=8D=E6=98=AF?= =?UTF-8?q?=E5=90=8C=E4=B8=80=E6=97=B6=E5=88=BB=EF=BC=88=E9=99=84=E5=AE=9E?= =?UTF-8?q?=E6=B5=8B=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 用户澄清"是抓取的窗口老是会错位"。把几种常见猜测逐一实测排除: 两条通道元素树不一致(✗ 逐项相同)、CSS 缩放没跟着算(✗ 缩放比正确、 框位置与理论值一致)、窗口 resize(✗ 预览列固定 320px)、列表索引错位 (✗ indexOf 保住原始序号)。 真因是取数时序: /api/uiauto/screenshot 0.4s + /api/uiauto/elements 1.8s(两次请求)= 间隔约 1.8s; 换成原生 u2 背靠背也仍有约 1.4s(dump 本身就要 1.3~1.8s,设备端开销改不动)。 界面只要在动(信息流/视频/动画),这两秒就足以让元素位置全变 → 框永远落在旧位置。 因为是**每次都发生**,所以表现为"老是错位"而不是偶发。 解法(写进文档待排期):①新增 /api/uiauto/snapshot 一个请求取齐(也正是 "用原始 u2"的做法,间隔降到 ~1.4s);②抓取前后各截一张做校验,不一致就 明确提示"界面在变化中,请停在静止界面再抓",而不是悄悄给一个错位的框。 --- doc/research/U2_ELEMENT_SELECTORS.md | 40 ++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/doc/research/U2_ELEMENT_SELECTORS.md b/doc/research/U2_ELEMENT_SELECTORS.md index 3cbf648..6125bab 100644 --- a/doc/research/U2_ELEMENT_SELECTORS.md +++ b/doc/research/U2_ELEMENT_SELECTORS.md @@ -85,6 +85,44 @@ --- +## 三·补:抓取弹窗"老是错位"的根因 —— **截图和元素树不是同一时刻** + +(2026-09-13 追加,用户反馈"抓取的窗口老是会错位") + +先把几个常见猜测逐一排除(都实测过): + +| 猜测 | 实测结果 | +|------|---------| +| 两条通道元素树不一致 | ✗ 排除:节点数/各 id 个数逐项相同 | +| 截图被 CSS 缩放了、框没跟着缩 | ✗ 排除:`scaleX=clientWidth/naturalWidth` 算得对,实测框位置与理论值一致 | +| 窗口 resize 后没重算 | ✗ 排除:预览列固定 320px,resize 不影响 | +| 列表索引与框的 `data-idx` 对不上 | ✗ 排除:用 `indexOf` 保住原始序号,过滤后也不乱 | + +**真因:截图与元素树分两次取,中间隔了 1~2 秒。** + +| 取数方式 | 截图 | 元素树 | 两者时间差 | +|---|---|---|---| +| 现在(`/api/uiauto/screenshot` + `/api/uiauto/elements` 两次请求,走 uiautodev)| 0.4s | 1.8s | **约 1.8 秒** | +| 原生 u2 背靠背(同一个连接)| 0.3s | 1.4s | **约 1.4 秒** | + +元素树的 dump 本身就要 1.3~1.8 秒(设备端 uiautomator 的开销,改不动)。 +界面**只要在动**(抖音信息流、视频、加载动画…),两秒足够让元素位置全变 → +**框永远落在旧位置上** —— 这就是"老是错位",不是偶发。 + +### 解法 + +1. **一次请求取齐**(推荐,也是用户说的"用原始 u2"): + 新增 `GET /api/uiauto/snapshot?serial=X`,服务端用**一个 u2 连接**背靠背 + `dump_hierarchy()` + `screenshot()`,返回 `{image, elements}`; + 前端只调这一个接口 → 天然同源,间隔从 ~2.2s 降到 ~1.4s。 +2. **双截图校验**(关键:让失败可见而不是悄悄错位): + 抓取时前后各截一张,两张**不一致就明确提示**"界面在抓取过程中变化了, + 请让设备停在目标界面再抓",而不是给一个已经错位的框。 +3. 文档里明确写:**抓元素要让设备停在静止界面**(设置页、已加载完的页面), + 别在视频播放/信息流滑动中抓。 + +--- + ## 四、建议的改动(待排期) 1. **抓取器(`core/uiauto_helper.py`)**:同一 id 出现多个实例时,**优先产出 @@ -96,3 +134,5 @@ 其余在编辑器里逐个复核。 4. **运行期**:`click` 未命中时,日志里顺带 dump 一下"同 id 现在有几个实例", 让"序号错位"当场可诊断(现在是干巴巴一句"未找到元素")。 +5. **(针对第三节的"抓取错位")** 抓取接口合并成一个快照接口 + 双截图校验, + 具体见第三节「解法」。