偏移量分页与游标分页
Scrapeless Agent Browser 为需要浏览分页网页的工作流提供云端浏览器自动化功能。
摘要
- 偏移分页用于标识一个位置。 它适用于编号页面以及在有界结果集中进行直接跳转。
- 游标分页用于确定续读位置。 客户端应保留返回的令牌以及生成该令牌的查询。
- 稳定排序需要一个唯一的决胜条件。 仅凭相同的时间戳无法可靠地定义页面之间的边界。
- 两种分页样式都不能保证数据集是冻结不变的。 快照行为必须是一个明确的服务合同。
| 维度 | 偏移分页 | 光标分页 |
|---|---|---|
| 请求模型 | 跳过指定数量的结果 | 从返回的 token 继续 |
| 导航 | 直接页面跳转是自然的 | 顺序遍历是自然的 |
| 更改数据 | 职位可能在请求之间发生变化 | 边界稳定性取决于排序方式和实现方式 |
| 数据库工作 | 较大的偏移量可能需要大量被跳过的工作 | 索引键集设计可以从边界位置进行查找 |
| 客户端状态 | 查询加页面或偏移量 | 查询加上不透明令牌和完成状态 |
| 快照语义 | 需要单独的一致性机制 | 需要单独的一致性机制 |
Offset 和 Cursor 实际标识的内容
偏移分页要求集合跳过一个基于位置的前缀并返回接下来的片段。游标分页则要求服务基于先前返回的边界继续。在偏移分页与游标分页的对比中,关键区别在于客户端在请求之间记住了什么:前者记住自己数到了多远,后者记住服务告诉它从哪里继续。
游标是一种 API 抽象,而键集分页是一种查询技术。令牌可能会编码排序值、引用服务器端状态,甚至封装一个偏移量。在假设一个不透明字符串意味着高效的数据库查找之前,请先查看其文档中描述的行为。 不透明页面令牌合约 提供了一个有用的模型:客户端在不解释其内容的情况下返回令牌。
为什么排序优先于页面大小
可预测的遍历需要一种能够区分每条记录的排序方式。仅按非唯一值排序会导致边界上的并列无法被消除。例如,一组文章中可能包含多个具有相同创建时间戳的条目。唯一标识符可以打破这种并列,只要它的排序和比较规则在各次请求之间保持一致。
请提供需要翻译的英文文本。 SQL 排序规则 使缺少显式排序变得具有意义:数据库不承诺提供有用的默认顺序。与集合运行一起记录完整的排序规范。将升序改为降序、更改过滤条件或更改依赖区域设置的比较方式,都可能使已保存的续传点失去其原有含义。
写入期间偏移分页的行为
当较早的记录被插入或删除时,偏移边界可能会发生变化。设想一个假想的列表,其中第一页以项目 D 结尾。在 A 之前插入一个新项目会改变后续记录的位置。再请求跳过原先的页长时,可能会让 D 再次出现在下一段切片中。删除一个较早的项目则可能会将原本未被看到的记录移动到已被跳过的前缀中。
这些示例描述的是位置变化,而不是特定 API 中的缺陷。对于一个规模较小、相对稳定的管理列表,并且用户重视带编号的导航时,偏移分页依然很有用。 LIMIT 和 OFFSET 语义 还要解释为什么较深的偏移量会很昂贵:即使是被跳过的行,也仍然需要服务器进行处理。在设置导航限制之前,先测量你实际的已过滤查询。
键集游标的适用场景及其局限
键集分页可以在最后一次观察到的排序元组之后继续,而无需重新计算之前的位置。在合适的索引和查询计划下,这避免了与深度偏移相同类型的跳过工作。它还避免了一些由于在边界之前插入数据而导致的位置移动。这个好处属于实现本身,而不是标记格式。
可变排序键仍然是一个问题。如果某个条目在你经过其原始位置之后更改了其排名分数,它就可能移入或移出未访问区域。一次删除操作可能会使边界记录消失。一个正确的服务必须定义其令牌在这些情况下的行为方式。对于需要精确历史成员集合的导出,应请求快照或其他显式的一致性边界。
作为消费者阅读续约合同
响应契约决定了消费者何时停止。服务可能返回专用的 next 标记、next 链接或结构化的分页信息。不要仅仅因为页面很短就推断已完成,除非 API 明确定义了该行为。按字节保留标记,包括其编码,并且不要根据可见的记录 ID 伪造 next 标记。
The GraphQL 连接模型 分隔记录边界、游标和页面信息。其 forward 和 backward 参数表明游标导航可以支持双向移动。但这种支持并不意味着可以进行任意页码跳转。应根据实际服务提供的操作来设计接口,包括令牌过期以及对更改筛选条件的任何限制。
在推进检查点之前持久化记录
只有当检查点对应于持久化的输出时,它才是有用的。在将其下一个游标标记为已提交之前,先保存当前页面及其来源。否则,如果一个进程在这些操作之间停止,它可能会在从未被存储的记录之外恢复。将检查点和输出边界视为一个应用层的一致性问题。
一个实用的记录封装包含源查询、集合标识、请求的排序方式、获取时间、记录标识以及续传状态。将凭证保持在该封装之外。当令牌过期时,保留已完成的输出并遵循文档中记录的重启路径。通过稳定记录标识进行去重可以保护目标免受重复观测的影响,但它无法恢复从未被观测到的条目。
将模型应用于浏览器分页
浏览器分页需要发现界面背后真正的续页机制。编号控件可能会更改 URL、提交表单、更新 JSON 请求,或向 DOM 追加记录。外观完全相同的“下一页”按钮在另一个网站上可能代表完全不同的机制。在对页面进行自动化处理之前,先确定是哪种操作在更改底层记录集。
Scrapeless Agent 浏览器 当导航需要渲染控件时,为浏览器层提供支持。它不会将基于偏移量的网站转换为快照 API。 分页获取模式 涵盖编号页面、“下一页”链接和滚动。保持源导航状态与目标检查点明确区分,尤其是在浏览器显示已收集的记录时。
将页面完成与集合完成分离
一个已完成的页面是关于某个响应的证据,而一个已完成的集合则是关于遍历契约的声明。一个空的 DOM 区域可能意味着加载尚未完成、筛选条件发生了变化,或者数据源实际上没有任何记录。在将“缺失”视为结束之前,先验证预期的页面标识和集合容器。
对于浏览器运行,同时捕获活动的筛选条件和排序方式以及最终观察到的记录标识。对于 API 运行,保留已记录的终端续传状态。如果来源提供了总数,判断该总数是否属于相同的快照和筛选条件。不断变化的头部统计数量是有用的上下文,但不应覆盖权威的续传信号。
通过导航和一致性要求进行选择
当用户需要直接的编号访问并且集合的规模足够有限可以支持这种方式时,选择偏移分页。当对大型且不断变化的集合进行顺序遍历是主要工作负载时,选择有文档说明的键集游标设计。如果你要使用现有服务,应当适应其契约,而不是重新给其机制贴标签以匹配某种偏好的架构。
对于一个新的 API,写明记录是否会改变排序位置、游标是否会过期,以及读取方是否需要历史一致性。浏览界面和财务导出可能需要不同的端点。因此,偏移量分页与游标分页既是产品决策也是查询决策:正确答案取决于你承诺支持的用户操作。
在扩展遍历之前先进行验证
遍历测试应验证成员资格和边界,而不仅仅是成功的响应。使用一个受控数据集,其中包含重复的排序值、缺失的可选字段以及在请求之间进行的编辑。将收集到的标识集合与预期集合进行比较。包括在写出结果之后执行一次重启,以便实际检验检查点行为,而不仅仅是对其进行描述。
在不同深度测量页面延迟、输出重复、缺失的身份以及检查点存储成本。将假设性示例与生产环境测量明确区分开来。当浏览器获取是设计的一部分时,请咨询 代理浏览功能模型 并比较相关用法基准 无抓取定价更多的工人并不能修复含糊的指令或损坏的完成规则。
结论
偏移分页适合直接按位置访问;游标分页适合在集合中持续往前遍历。先固定排序方式并定义一致性要求,然后测试插入、删除、令牌过期和中断写入如何影响采集到的记录集。一个可持久化的检查点和有文档记录的完成信号,比分页控件的外观更重要。
构建你的下一条数据工作流
在采集层使用 Scrapeless Agent Browser,并在设计其余管道时应用这份对比。
立即注册即可获得 $5 免费额度 — 无需信用卡.
领取你的 $5 额度 →常见问题
问:游标分页总是比偏移分页更快吗?
游标分页并不总是比偏移分页更快。不透明令牌可能只是包了一层 offset,或包含昂贵的服务器状态。性能取决于过滤条件、索引、排序方式、查询计划以及结果深度。应比较实际负载,而不是把 API 参数名当成基准。
问:游标能完全避免重复和缺失记录吗?
游标并不能完全避免所有重复或缺失记录。稳定的键集边界可以解决部分位置偏移问题,但可变的排序键和集合成员变更仍然会影响遍历。要获得精确的历史导出,需要有文档说明的快照或其他合适的一致性保证。
问:游标分页能支持向后导航吗?
当 API 暴露该操作时,游标分页可以支持向后导航。客户端通常需要合适的边界令牌和方向参数。要保持文档中规定的排序;反转展示顺序与更改底层查询排序是两件不同的事。
问:爬虫应该解码返回的游标吗?
除非服务明确为客户端使用记录了游标格式,爬虫都应把返回的游标视为不透明的。应与原始过滤条件和排序一起保存。为查看而解码令牌并不意味着支持构造或编辑令牌。