Nstproxy 现已升级为 Nstdata。了解此次变化。
周一至周五 09:00 - 18:00(UTC+08:00) 公司地址
19H MAXGRAND PLAZA NO.3 TAI YAU STREET SAN PO KONG, KOWLOON HONG KONG ©2026 NST LABS TECH LTD. 保留所有权利。
使用 Node.js 进行网页抓取:Puppeteer 和 Playwright 指南
Kai Watanabe Scraping Infrastructure Evangelist
使用 Node.js 进行网页抓取:Puppeteer 和 Playwright 指南 TL;DR
使用 Node.js fetch 处理被允许的静态页面或文档 API;当所需数据在 JavaScript 或交互后出现时再添加浏览器。
Puppeteer 和 Playwright 都可以控制浏览器。Playwright 的定位器和多浏览器模型通常适合维护的工作流;Puppeteer 是一个专注于 Chrome 的自动化选择。
等待一个有意义的元素或响应,而不是固定的休眠或通用 networkidle 事件。在提取之前验证结果页面的状态。
在一个有界作业中重用浏览器资源,可靠地关闭它们,并存储源 URL、提取时间、解析器版本和拒绝原因。
Nstdata Crawl 可以通过其 API 或文档化 SDK 向 Node.js 应用程序提供渲染页面获取、网站发现、LLM 准备好的输出和内置代理路由。
Node.js 爬虫何时应该使用浏览器?
当一个被允许页面的所需内容是由客户端 JavaScript 或无法通过文档化源 API 表示的用户行动创建时,Node.js 爬虫应该使用浏览器。首先检查初始 HTML 和网络面板。如果源通过官方 API 提供稳定的 JSON,使用浏览器将增加成本和操作复杂性,而不会改善字段语义。如果页面依赖于 React、Vue 或另一个由客户端渲染的应用程序,fetch() 可能仅返回一个空壳。
Nstdata Crawl 是获取页面内容而不是浏览器交互序列的另一种获取路径。
Playwright 网络指南 显示可以检查浏览器请求和响应,而 Puppeteer 交互指南 描述了元素和输入操作。这两个工具都在源授予的访问权限内工作。浏览器不提供进入私人页面或忽略挑战的权限。
Puppeteer 和 Playwright 在抓取方面有什么比较?
根据所需的交互和团队的操作栈进行选择,而不是基于通用的“最佳”声明。Puppeteer 具有直接的浏览器/页面模型,常用于以 Chrome 为导向的脚本。Playwright 提供了类似的模型,具有浏览器上下文、基于角色的定位器以及对 Chromium、Firefox 和 WebKit 的文档支持。这两者都需要浏览器安装、内存管理、超时、选择器和源感知请求速率。
决策 Puppeteer Playwright 最佳契合 专注于 Chrome 工作流 维护的多浏览器或以定位器为重的工作流 页面选择 CSS 和自定义选择器语法 带有角色、文本、CSS 和 XPath 的定位器 API 隔离 可用的浏览器上下文 浏览器上下文是一个核心工作单位 网络检查 请求/响应事件和拦截 请求/响应事件、路由、API 测试 操作负担 浏览器生命周期、内存、打包 浏览器生命周期、内存、打包
不要假设一个包的文档可以保证在特定网站上的成功。网站行为和权限决定工作流是否合适。Playwright 定位器文档 推荐反映用户如何识别元素的定位器;这可以减少当生成的 CSS 类名变化时的脆弱性。
开始之前需要什么? 使用受支持的 Node.js 版本、批准的测试 URL、预期的内容标记和最大页面预算。对于 Playwright 库,安装 playwright 及当前官方说明所需的浏览器二进制文件。对于 Puppeteer,安装 puppeteer,它包括其文档化的浏览器下载行为;查看当前的 Puppeteer 入门指南 以适应你的环境。
mkdir node-scraper && cd node-scraper
npm init -y
npm install playwright puppeteer
npx playwright install chromium
在 package.json 中设置 "type": "module" 以支持下面的 ESM 示例,或者将其保存为 .mjs。在编写选择器之前,验证一个无头浏览器可以在你的部署镜像中启动。[截图:浏览器开发工具显示目标内容在客户端请求后出现。]
如何使用 Playwright 抓取渲染页面?
方法 1:使用定位器和明确的接受检查 步骤 1. 检查被批准的页面并识别一个稳定的标题、文章或项目元素。这个示例使用 example.com 演示浏览器设置;它不需要动态目标。
步骤 2. 创建一个上下文,导航时设定超时,并读取可见的标题:
import { chromium } from 'playwright' ;
const browser = await chromium . launch ( { headless : true } ) ;
try {
const context = await browser . newContext ( ) ;
const page = await context . newPage ( ) ;
const response = await page . goto ( 'https://example.com/' , { waitUntil : 'domcontentloaded' , timeout : 30000 } ) ;
if ( ! response ?. ok ( ) ) throw new Error ( ` 导航失败: ${ response ?. status ( ) } ` ) ;
const heading = page . getByRole ( 'heading' , { level : 1 } ) ;
await heading . waitFor ( { state : 'visible' , timeout : 10000 } ) ;
const title = ( await heading . textContent ( ) ) ?. trim ( ) ;
if ( ! title ) throw new Error ( '期望的标题为空' ) ;
console . log ( { url : page . url ( ) , title } ) ;
await context . close ( ) ;
} finally {
await browser . close ( ) ;
}
步骤 3. 在您的实际许可页面上,将标题定位器替换为页面的有意义内容标记,然后验证提取的字段。导航响应可以是 200,而呈现页面是一个同意墙,因此在存储之前检查 DOM 和接收记录夹具。
如何使用 Puppeteer 执行相同的任务?
方法 2:使用页面和范围选择器 步骤 1. 保持相同的批准 URL 和期望标题,以便比较测量库,而不是两个不同的目标。
步骤 2. 在 finally 块中启动和关闭浏览器:
import puppeteer from 'puppeteer' ;
const browser = await puppeteer . launch ( { headless : true } ) ;
try {
const page = await browser . newPage ( ) ;
const response = await page . goto ( 'https://example.com/' , { waitUntil : 'domcontentloaded' , timeout : 30000 } ) ;
if ( ! response ?. ok ( ) ) throw new Error ( ` 导航失败: ${ response ?. status ( ) } ` ) ;
await page . waitForSelector ( 'h1' , { timeout : 10000 } ) ;
const title = await page . $eval ( 'h1' , node => node . textContent . trim ( ) ) ;
if ( ! title ) throw new Error ( '期望的标题为空' ) ;
console . log ( { url : page . url ( ) , title } ) ;
} finally {
await browser . close ( ) ;
}
步骤 3. 映射实际网站的字段,验证它们并存储源元数据。如果页面需要点击或滚动,请在操作后等待新项或响应。Puppeteer 请求拦截指南 指出拦截的请求在继续、响应或中止之前会停止;仅在必要时添加拦截。
如何在生产中保持浏览器抓取的稳定性? 根据测量的内存和源限制来限制页面和浏览器并发。重用一个浏览器以处理有限数量的页面,但使用上下文隔离会话,并在内存无限增长之前回收工作者。围绕导航和有意义的元素等待设置超时。当保留策略允许时,保存失败页面的屏幕截图或原始 HTML;这有助于区分标记漂移、部分渲染和挑战页面。
Nstdata 如何帮助 Node.js 团队收集网页内容? Nstdata Crawl 是一个用于 LLM 准备数据的 Web 爬虫 API,解决了重复渲染、网站发现和输出转换工作。它可以从一个 URL 开始,在配置的限制内发现链接页面,渲染 JavaScript,并通过 REST API 或文档化的 Node SDK 返回工件。该应用程序仍然定义项的身份、验证、存储和源策略。
LLM 准备格式: Markdown 对于 RAG 和代理上下文非常有用;HTML 和原始数据保留可解析结构;链接支持发现;屏幕截图和 PDF 保留可见页面状态。Crawl 文档 列出了这些输出,并解释了更大工件的参考令牌。
内置代理: 标准托管请求使用 API 密钥,而无需单独的代理 Host、Port、Username、Password 或 Protocol 设置。这消除了 Node.js 应用程序中的网络接线,同时源权限和使用规则仍然适用。
任务和范围控制: maxDepth、maxPages、包含和排除规则限制站点作业。状态和页面端点使您的应用程序能够协调已完成、失败和接受的记录。
如何将 Nstdata Crawl 连接到 Node.js? 步骤 1. 在 仪表盘 → 爬虫游乐场 ,获取 API 密钥并将其存储在 NSTDATA_API_TOKEN 中。安装官方文档中描述的 SDK:
npm install @nstdata-ai/crawl
步骤 2. 通过文档中的 SDK 方法提交单个已批准的页面:
import { NstDataClient , Format } from '@nstdata-ai/crawl' ;
const client = new NstDataClient ( process . env . NSTDATA_API_TOKEN ) ;
const result = await client . submitScrapeTaskSync ( {
url : 'https://example.com/' ,
formats : [ Format . MARKDOWN , Format . HTML ] ,
timeout : 60000 ,
onlyMainContent : true ,
} ) ;
console . log ( result ) ;
步骤 3. 在将内容映射到您的架构之前检查任务成功与页面状态。对于一个站点,使用 submitCrawlTask 进行有限深度和页面的提交,然后查询状态。此示例遵循官方 API 形状;需要一个有效的密钥和确切安装的包才能执行。不要在未进行验证的情况下声称爬虫返回您的最终业务对象。
在将浏览器抓取工具投入生产前,您应该测量什么? 测量每分钟浏览器接受的记录数、峰值内存、页面导航延迟、渲染等待、拒绝率以及诊断一个失败所需的时间。运行一个包含正常页面、重定向、缺失字段、客户端渲染页面以及应该被拒绝的页面的代表性集合。一个快速获取但经常留下上下文的浏览器进程,在负载下会变得不稳定。在有限的批处理之后关闭上下文和页面,并根据测得的内存回收浏览器,而不是根据任意假设。
将源故障与库故障分开。在 page.goto() 中的超时可能意味着导航从未完成;成功导航后缺少的定位符则可能意味着页面已更改或返回了挑战。给予这些结果独特的代码并保存允许的屏幕截图或 HTML 示例。当一个站点有多个模板时,按模板跟踪接受的产出。单一的全局通过率可能会掩盖一个损坏的产品详情页,而分类页面仍然继续工作。
为了在 Puppeteer、Playwright 和托管 API 之间做出公平的选择,运行相同的 URL 和接受规则。包括浏览器下载和更新工作、部署镜像大小、工作内存、重试行为和随时诊断。最佳选择是能够在源的权限和团队的运营预算内提供有效记录的选项。
常见问题 问:Puppeteer 或 Playwright 对于每个抓取器来说更快吗?
都没有普遍的端到端优势。测试实际页面、渲染等待、接受的输出和浏览器资源成本。
问:我应该使用 networkidle 来等待每个页面吗?
不。更喜欢特定于页面的内容标记或响应;分析和长期连接可能会使通用的网络空闲信号不可靠。
问:Nstdata Crawl 能取代业务字段验证吗?
不能。爬虫获取和转换页面,而您的应用程序决定字段是否代表正确的实体并适合存储。
不。它检索 HTTP 响应;当内容仅在客户端 JavaScript 后出现时,需要一个浏览器或托管渲染路径。
Lena Zhou
Oct. 30th 2026
支持 JavaScript 渲染,成功率达 99.8%
将任意网站转换为 Markdown、HTML、JSON、链接、PDF 等格式,无需管理爬取基础设施。 开始免费爬取 →