docs(research): 补「抓取弹窗老是错位」的真因——截图与元素树不是同一时刻(附实测)

用户澄清"是抓取的窗口老是会错位"。把几种常见猜测逐一实测排除:
两条通道元素树不一致(✗ 逐项相同)、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);②抓取前后各截一张做校验,不一致就
明确提示"界面在变化中,请停在静止界面再抓",而不是悄悄给一个错位的框。
This commit is contained in:
2026-09-13 21:01:53 +08:00
parent a94f63f0bf
commit ee559786e7
+40
View File
@@ -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 出现多个实例时,**优先产出 1. **抓取器(`core/uiauto_helper.py`)**:同一 id 出现多个实例时,**优先产出
@@ -96,3 +134,5 @@
其余在编辑器里逐个复核。 其余在编辑器里逐个复核。
4. **运行期**:`click` 未命中时,日志里顺带 dump 一下"同 id 现在有几个实例", 4. **运行期**:`click` 未命中时,日志里顺带 dump 一下"同 id 现在有几个实例",
让"序号错位"当场可诊断(现在是干巴巴一句"未找到元素")。 让"序号错位"当场可诊断(现在是干巴巴一句"未找到元素")。
5. **(针对第三节的"抓取错位")** 抓取接口合并成一个快照接口 + 双截图校验,
具体见第三节「解法」。