即使页面无法判断的滚动事件

发布于

现代的无限滚动页面并不是因为你请求的好而加载它们的内容。许多页面在处理滚动事件时会检查 `event.isTrusted`,这是浏览器设置的标志,用来区分来源于实际用户(操作系统输入管道)的输入与由 JavaScript 合成的输入(如 `element.dispatchEvent`、`window.scrollBy`)。如果事件标记为 `isTrusted: false`,页面会直接拒绝获取更多内容。这就像一道礼貌的小障碍,确实很难越过:根据规范,JavaScript 不能在合成事件上设置 `isTrusted`。

这就为 [Scrapewright](https://github.com/singhand-labs/scrapewright) 带来了有趣的问题,这是一款开源的 Chrome 扩展,它的抓取工具必须触发那些应用此过滤的页面上懒加载内容。程序化的 `scrollBy` 永远是 `isTrusted: false`。该项目提供的解决方案是仓库中最有趣的技巧:**通过 Chrome DevTools 协议的输入域发送的 wheel 事件中,`isTrusted: true`** — 因为它们通过与操作系统相同的输入管道进入 Chrome。

## 机制

简要流程如下:

1. 步骤脚本调用 `$scrollToBottom`(一种 DSL 原语)。正常路径首先:程序化滚动,并进行停滞检测——如果内容停止增长,程序化滚动正在被过滤。
2. 一旦检测到停滞,扩展暂时附加 Chrome DevTools 协议到标签页(`chrome.debugger.attach`)——这是扩展调试 API,用户会看到标准的“正在调试”信息栏;没有任何隐藏内容。
3. 它发出 `Input.dispatchMouseEvent`,类型为 `'mouseWheel'`,并给定合成的 `deltaY`,目标是那个标签页。
4. CDP 的 `Input.*` 命令被注入到浏览器的输入层。结果的 wheel 事件沿着与触控板相同的路径传播:输入管道 → 渲染器 → 事件侦听器 — 其中包含 **`isTrusted: true`**。使用 IntersectionObserver 驱动的加载器和信任检查处理程序的行为与人类相同。
5. 调试器会断开连接。尝试次数有限(每次 `$scrollToBottom` 调用的小预算),因此 hopeless 的页面会很快失败,而不是缓慢处理。

所以:在 Chrome 中生成可信的 wheel 事件的唯一程序性机制是 CDP Input — 并不是因为存在bug,而是因为 CDP Input **就是**浏览器可编程的通往真实输入管道的正门。来自 JavaScript 的合成 `InputEvent` 永远不被信任;CDP 注入的事件在构造上是“真实的”。

## 细微差别使其值得阅读

**它仅在活动标签页中工作。** `Input.dispatchMouseEvent` 在后台标签页中可能会挂起或无效,因为 Chrome 只为聚焦窗口的活动标签页生成合成器帧 — 这是一个分离的架构节流。因此,该项目将 CDP 输入与一个 **标签页激活** 层结合在一起(激活抓取标签,保持其活跃,在抓取标签关闭时返回用户到上次点击的标签)。两个“无关”的 Chrome 行为原来是一个要求。

**检测表面是设计决策。** 附加 `chrome.debugger` 是可见的(信息栏)并且可观察的(存在 `console.debugger` 检测技巧、`Runtime.enable` 通知等)。该仓库故意仅限于 `Input.*` 命令 — 不涉及 `Runtime.*`、`Network.*` 或 `DOM.*` 的干预 — 最小化了足迹和滥用潜力。这是一个抓取工具,只提升了一层,仅限于一个目的,并有限制。

**这是后备方案,而非默认选择。** 普通的程序性滚动在大多数网站上工作得更好且更快;可信的 wheel 路径存在于那些加载程序根据信任进行过滤的网站类别。停滞时提升,而不是一直开启 CDP,使常见路径保持轻便,而重路径则较少。

## 这合法吗?

这个问题理应具有与代码同样的诚实。`isTrusted` 障碍旨在区分“有人在这里”和“代码在驱动”。CDP 输入故意模糊了这一区别——这正是它的功能,而这也是企业 RPA 工具和谷歌自家的 Puppeteer(`page.mouse.wheel`)所暴露的机制。Scrapewright 在 **你的浏览器中使用,针对你的会话可以访问的页面**,来读取你有权查看的内容——伦理上的负担在于你有权查看什么,而不是输入机制。该仓库同样明确其局限性:这不是匿名工具,其明确的范围是重复、定向提取,而非大规模爬虫。如果你在其基础上进行开发,请保持相同的界限。

作为纯浏览器工程,这是整个技术栈中一个可爱的角落:规范级别的安全标志 → 架构帧生成规则 → 输入管道注入 → 激活协调,所有这些都相互配合,以产生一个懒加载的馈送滚动。它所处的五层反节流栈中的整个文档均在白皮书中有详细说明 (§9),而这是今年任何开源仓库中最好的 Chrome 内部文档之一。

**仓库:** [github.com/singhand-labs/scrapewright](https://github.com/singhand-labs/scrapewright) — GPLv3, `lib/renderer-activation.js` 和 `lib/scroll-ops.js` 是开始阅读的地方。

---

原文链接:[点击查看](https://www.v2ex.com/t/1236297)

评论

暂无评论。

0.065037s