什么是 DOM?
Scrapeless Agent Browser 提供托管的浏览器环境,用于检查和交互动态网页。
总结
- DOM 将当前文档表示为一个对象树。
- HTML 源码与实时文档中包含的信息可能不同。
- 字段选择必须保留每条记录与其各个取值之间的对应关系。
- 文档上下文和应用状态决定了提取器可以观察到什么。
DOM 表示什么
DOM(文档对象模型,Document Object Model)是一个将文档表示为对象树的编程接口。浏览器从 HTML 构建该树,并允许脚本读取或更改其中的节点。 DOM Standard 定义了节点树和事件的共享模型。JavaScript 通常会使用这一模型,但 JavaScript 与 DOM 是不同的事物:前者是一种语言,后者是访问文档的接口。
在 Web 数据工作中,有用的区分是:服务器返回的 HTML 与页面脚本运行之后存在的文档之间的差别。一个商品价格可能在最初的响应中缺失,而稍后才在浏览器中出现。只要应用创建了该价格,DOM 检查就可以发现它。仅仅读取最初的响应,无法发现尚未被创建的元素。
可以把一个商品卡片想象成包含标题、链接和价格的容器。卡片元素是父元素,内部嵌套的是子元素。同一列表中的两个卡片彼此是兄弟元素。显示在标题内部的字符占据的是文本节点。这些关系让提取器可以先识别正确的记录再读取其字段,而不是在整页上收集所有看起来像价格的字符串。
HTML 源码、DOM 状态与屏幕像素
HTML 源码、DOM 状态和已渲染的屏幕描述的是页面的不同阶段。源码是输入文本;DOM 是当前的文档结构;已渲染的屏幕还取决于样式、布局、字体、视口以及其他渲染行为。一个节点可以存在于 DOM 中,同时对查看页面的人来说仍然是不可见的。
“ HTML parsing specification ”描述了浏览器如何从标记构建文档,以及它们如何处理格式错误的输入。当源文件与浏览器的 Elements 面板看起来不一致时,这一点很重要。浏览器可能在解析过程中修复了嵌套或插入了结构,然后应用脚本才对页面做出任何更改。
截图回答的是在特定视口中可见地显示了什么。DOM 快照回答的是在捕获时有哪些文档节点和属性可用。二者都不能单独证明目录中的每件商品都已加载。例如,一个虚拟列表可能只在文档中保留当前需要的条目,同时通过滚动呈现一个大得多的集合。
因此,提取规范应当指明其数据来源:原始 HTML、当前 DOM、可访问文本,或结构化数据源。把所有这些都笼统地称为“页面内容”,会掩盖差异,而这些差异之后看起来就像数据不一致。将所选的源类型与记录一起保存,这样审查者就知道采集方法当时实际上能观察到什么。
在不丢失记录边界的前提下读取元素
当选择从记录容器开始时,DOM 提取效果最好。先定位商品卡片、文章结果或表格行,然后读取该容器内的字段。如果在整个文档范围内分别选择标题和价格,一张促销卡片或一个缺失的价格就可能让列表错位,把价格附加到错误的商品上。
CSS 选择器描述匹配元素的条件。 Selectors specification 区分了后代、子元素等结构性关系。在实际操作中,“这个卡片内部某个位置的链接”和“直接在这个卡片下方的链接”是不同的要求。选择能反映页面结构的关系,然后用具有代表性的记录对其进行验证。
元素的文本和属性也可能承担不同的作用。一个链接的可见文本可能是“View details”,而其目标地址才标识商品本身。价格标签可能包含货币符号和促销限定语。先保留原始文本,直到这些含义被拆分清楚;如果一开始就删除所有非数字字符,可能会破坏关于价格区间或分期价格的信息。
在可能的情况下,要优先使用稳定的属性或有意义的结构关系。由构建过程生成的类名,可能在页面业务逻辑未改变的情况下发生变化。不过,没有任何选择器是永久可靠的。应维护预期记录的示例,并在接受新的提取结果为“完成”之前,标记缺失的标识性字段。
时机会改变你读取到的文档
一次 DOM 读取观察到的是应用生命周期中的某个瞬间。初始文档可能包含占位符,下一状态可能显示结果,而再后一个状态可能在用户选择地点后更新库存情况。一次成功的导航并不能说明你的流程所需字段已经就绪。
用记录来定义“就绪”状态。一个有用的条件可以是:商品标识符及其选定规格已经出现,并且加载指示器消失。页面级的网络条件在分析或广告继续发出请求时,往往是糟糕的替代方案。固定延迟同样只是一种猜测,除非在之后检查预期状态是否已经达成。
假设鞋类页面最初显示的是所有尺码中的最低价格。选择尺码后,价格发生变化。捕获第一个值并将其标记为所选尺码的价格,是一种语义错误,尽管选择器返回了有效文本。应记录交互状态,然后读取属于该状态的值。
对于可重复运行,写下起始 URL、任何所需的选取条件、就绪规则,以及用于确认正确记录的字段。这些步骤是抽取契约的一部分。即使浏览器导航由某个服务管理,这些步骤也应保持显式。
框架、影子树与缺失内容
并非每一段内容都属于顶层文档树。一个 iframe 拥有自己的文档。一个 Web 组件可以将元素放入影子树中。绘制在画布上的内容可能没有与人眼可见文字相对应的普通文本节点。正是这些区别解释了,为什么某个在视觉上显而易见的值,可能在简单的、作用于整个文档的选择器中缺失。
当选择器没有返回任何内容时,先检查文档上下文。这个值是否在一个 frame 中?组件是否暴露了可访问的 shadow root?应用程序是否实际加载了相关的部分?在检查观察方法之前,不要断定数据源没有数据。
访问边界仍然适用。浏览器自动化工具并不会授予读取私人信息的权限,也不会移除文档上的限制。请将工作流程限制在你被授权使用的页面和交互范围内。如果现有界面未提供所需信息,应记录这一限制,而不是凭空编造数值。
通常,将缺失字段分类为可选、尚未加载、当前文档上下文之外或抽取失败是很有用的。这些标签可以告诉下游用户是应该接受一条不完整的记录,还是需要检查数据收集过程。单个空字符串无法表达所有这些含义。
实用的 DOM 检查实战指南
一次有用的 DOM 检查从一个已知页面和一个已知记录开始。打开页面,定位可见的记录,并检查其容器。将你看到的文本与实际的节点和属性进行对比。确认当相邻卡片具有不同布局时,相同的选择仍能识别出预期的卡片。
接下来,检查原始页面响应。如果其中已经存在该记录,对于那一特定提取任务,可能就不需要浏览器。如果内容只有在脚本运行或允许的交互之后才出现,那么受控浏览器就是适当的层。该决策取决于页面的行为,而不是工具的复杂程度。
对于一个假设的目录,测试一个普通商品、一个打折商品以及一个不可用商品。检查缺失价格是否会产生明确的不可用状态。验证折扣徽章不会被误认为实际销售价格,并且推荐轮播不会与主商品列表合并。
最后,保留一个小型审查样本,其中包含来源 URL、捕获时间、记录标识符、选定变体、原始字段文本和规范化值。该样本使后续的选择器更改可被审查。这样,无需重建整个浏览会话,就能够解释每个提取值为何属于其对应记录。
代理浏览器的适用场景
无抓取代理浏览器 为与动态页面交互提供受管浏览器环境。 代理浏览功能 涵盖浏览器操作;你的应用程序仍然决定检查哪个文档状态以及提取字段的含义。
托管浏览器可以免去你自行运行浏览器服务器的需求。它不会自动选择正确的产品匹配、区分分期付款与总价,或判断一条记录是否完整。请将这些检查保留在抽取和验证阶段,在那里业务规则是清晰可见的。
同样的分离也出现在 降价监控工作流程:呈现提供了对不断变化文档的访问,而比较则依赖于对产品身份和价格的一致解读。审查 无爬取定价 在估算浏览器使用情况时,应评估收集到的有效数据量,而不仅仅是导航成功率。
结论
理解 DOM 能让诊断浏览器抽取变得更容易。选择正确的文档上下文,等待达到相关状态,并在各自记录内读取每个字段。下一步有用的做法是检查一个具有代表性的页面,并详细记录在其数据可以被接受之前必须满足的所有条件。
构建你的浏览器数据工作流
从一个聚焦的样本开始,并检查支持你下一个决策的数据。
今天注册即可获得 5 美元的免费额度 — 无需信用卡.
领取您的 $5 额度 →常见问题解答
问:DOM 和 HTML 是一样的吗?
DOM 是内存中的文档模型,而 HTML 是用于描述文档的标记格式。浏览器的解析以及后续脚本的活动可能会使当前的 DOM 与原始 HTML 不同。请选择与所需信息相匹配的来源。
问:DOM 是 JavaScript 的一部分吗?
DOM 是一个供 JavaScript 使用的 Web 平台接口。JavaScript 也可以在没有浏览器文档的环境中运行,因此了解这门语言并不意味着在每个运行时中都一定有可用的 document 对象。
问:DOM 快照是否包含每一个可见的细节?
DOM 快照并不能完整描述渲染后的屏幕。样式、布局、canvas 内容、框架以及应用程序状态都会影响可见内容。当某个字段的含义依赖其呈现方式时,应将文档检查与视觉检查结合起来。
问:为什么选择器只起作用一次然后就失效了?
选择器可能会因为标记、文档上下文或加载状态发生变化而停止匹配。分别检查这些条件。避免将空结果解读为底层产品、文章或数值已从源站点消失的证据。