🎯 一款可定制、具备反检测功能的云浏览器,由自主研发的 Chromium驱动,专为网页爬虫AI 代理设计。👉立即试用
返回博客

使用JavaScript和Node.js进行网络爬虫:Cheerio与Puppeteer

Daniel Kim
Daniel Kim

Lead Scraping Automation Engineer

15-Jun-2026

关键要点:

  • 第一个决定是静态与动态,它决定了整个工具链。 如果数据在初始 HTML 中,使用 Cheerio 进行解析;如果 JavaScript 构建数据,则需要像 Puppeteer 这样的真实浏览器。
  • Cheerio 是解析器,而不是浏览器 —— 这正是重点。 它加载 HTML,并以原生速度提供 jQuery 风格的选择器,没有渲染开销,仅适用于内容已在标记中的页面。
  • Puppeteer 渲染,因此它查看用户所见。 对于客户端渲染的页面、无限滚动和交互后面的内容,Puppeteer 运行 JavaScript 并交给你完成的 DOM。
  • 两者都在同一个 Scrapeless 会话中运行。 通过云浏览器获取 HTML,然后使用 Cheerio 解析或通过 Puppeteer 实时提取——底层具有相同的反检测和住宅出口。
  • 并行验证。 以下相同的目录页面通过 Cheerio 产生 20 项,通过 Puppeteer 也产生 20 项——证明当内容存在时,两条路径一致。
  • 免费开始。 新的 Scrapeless 账户包括免费的抓取浏览器运行时——在 app.scrapeless.com 注册。

介绍:为页面选择正确的工具

JavaScript 和 Node.js 非常适合网络抓取——这是浏览器运行的相同语言,具有成熟的 HTTP 和 HTML 生态系统。但是“用 Node 抓取”立即分为两种截然不同的工作,选择错误的一个会浪费精力。

如果你想要的数据已经在页面的初始 HTML 中,你根本不需要浏览器——你需要的是一个快速的解析器。这就是 Cheerio:加载标记,运行选择器,完成。如果数据是在加载后由 JavaScript 构建的——一个 React 应用程序、无限滚动的动态信息、仅在点击后出现的内容——那么解析器什么也看不见,因为它解析的 HTML 是一个空壳。这就是 Puppeteer(或 Playwright)发挥作用的地方:它运行页面的 JavaScript 并给你渲染的 DOM。

两个工具下的实际问题是访问:真实网站会进行指纹识别、限速和地域封锁。本指南在 Scrapeless 抓取浏览器上同时运行这两种方法——一种反检测云浏览器——因此获取成功,然后展示何时使用 Cheerio,何时使用 Puppeteer。以下两种路径都在同一页面上实时运行。


静态与动态:如何判断

静态(Cheerio) 动态(Puppeteer)
数据的位置 在初始 HTML 中 加载后由 JS 构建
工具 解析器 真实浏览器
速度 快,开销低 较慢,渲染页面
适用情况 服务器渲染的页面、文章、目录 单页面应用程序、无限滚动、点击后内容

快速测试:查看页面源代码(而不是检查器)。如果数据在原始 HTML 中,Cheerio 就足够了。如果源代码是一个几乎空的壳,内容仅在实时 DOM 中显示,则需要 Puppeteer。


为什么选择 Scrapeless 抓取浏览器

Scrapeless 抓取浏览器是一个可定制的、反检测的云浏览器,专为网络爬虫和 AI 代理设计。对于 Node 抓取,它特别提供:

  • 标准的 Puppeteer 连接 —— Puppeteer.connect() 返回一个正常的 Browser,因此你的代码没有变化。
  • 云端 JS 渲染 —— 动态页面实际上构建它们的内容,因此 page.content()(用于 Cheerio)和实时提取都能正常工作。
  • 195多个国家的住宅代理 —— 准确的出口确保获取成功并保持一致。
  • 反检测指纹识别 —— 会话呈现为真实浏览器,因此页面渲染,而不是挑战。
  • 会话持久性 —— 在多页面运行之间保持 Cookie 有效。

在免费计划上获取你的 API 密钥,访问 app.scrapeless.com


前提条件

  • Node.js 18 或更高版本
  • Scrapeless 账户和 API 密钥——在 app.scrapeless.com 注册
  • 对 CSS 选择器有基本了解

安装

bash Copy
npm install @scrapeless-ai/sdk puppeteer-core cheerio
bash Copy
export SCRAPELESS_API_KEY="your_api_token_here"

连接

javascript Copy
import { Puppeteer } from '@scrapeless-ai/sdk';

const browser = await Puppeteer.connect({
  apiKey: process.env.SCRAPELESS_API_KEY,
  sessionName: 'js-node-scraping',
  proxyCountry: 'US',
  sessionTTL: 300,
});

const page = await browser.newPage();
await page.goto('https://books.toscrape.com/', {
  waitUntil: 'domcontentloaded',
  timeout: 60000,
});

路径 A — Cheerio(静态解析)

当内容在 HTML 中时,使用 page.content() 获取标记,并使用 Cheerio 解析。选择器 API 采用 jQuery 风格,因此阅读起来很自然:

javascript Copy
import * as cheerio from 'cheerio';

const html = await page.content();
const $ = cheerio.load(html);

const titles = $('.product_pod h3 a')
  .map((i, el) => $(el).attr('title'))
  .get();

console.log(titles.length, '—', titles[0]);
// 20 — A Light in the Attic

Cheerio 不会渲染任何内容——它只是解析你提供的字符串。这使得它在已经持有 HTML 时快速且理想。你也可以在任何来源的 HTML 上使用它,而不仅仅是浏览器。

在免费计划中获取你的 API 密钥:app.scrapeless.com


路径 B — Puppeteer(动态提取)

当内容由 JavaScript 构建时,从渲染页面的实时 DOM 中提取。相同的选择器,但在页面脚本运行后在浏览器中评估:

javascript Copy
const titles = await page.evaluate(() =>
  [...document.querySelectorAll('.product_pod h3 a')].map((a) => a.getAttribute('title')),
);

console.log(titles.length, '—', titles[0]);
// 20 — A Light in the Attic

在同一目录页面,两个路径返回相同的 20 个标题——因为内容在 HTML 中存在,无论哪种方法都有效。区别在于客户端渲染的页面:Cheerio 在原始 HTML 中找不到任何东西,而 Puppeteer 路径仍然返回项目,因为页面首先进行了渲染。

对于在交互时加载的动态内容,在提取之前驱动页面——滚动以获取懒加载内容,点击以显示,然后在结果上 waitForSelector

javascript Copy
await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
await page.waitForSelector('.product_pod', { timeout: 10000 });
// ...然后如上提取

选择它们之间的方式

  • 原始 HTML 中有内容吗? 使用 Cheerio——它更快、更简单。
  • 内容由 JavaScript 构建、无限滚动或在点击后出现吗? 使用 Puppeteer 进行渲染,然后提取。
  • 一个页面上都有内容? 很常见——用 Puppeteer 渲染,然后将 page.content() 传递给 Cheerio 如果你更喜欢其选择器在静态部分的易用性。

返回的内容

当数据存在时,任何路径都会生成相同的扁平列表:

json Copy
{
  "count": 20,
  "first": "A Light in the Attic"
}
// 实际捕获:Cheerio 和 Puppeteer 都从同一页面返回了 20 个标题。

一些诚实的观察:

  • 在不必要时不要渲染。 如果 HTML 已经有数据,Cheerio 完全跳过渲染成本。
  • 当源是一个外壳时渲染。 一个几乎为空的原始 HTML 与一个填充的实时 DOM 是使用 Puppeteer 的信号。
  • 在内容上等待,而不是时钟。 对于动态页面,waitForSelector 优于固定的 setTimeout
  • 选择器是共享知识。 相同的 CSS 选择器在 Cheerio 和 querySelectorAll 中有效,因此在路径之间移动成本低。

结论:一个决定,两个干净的路径

使用 JavaScript 和 Node.js 进行网页抓取归结为一个早期的调用——数据是在 HTML 中,还是由 JavaScript 构建?Cheerio 执行第一个案例,以解析速度处理;Puppeteer 通过渲染页面处理第二个案例。在 Scrapeless 抓取浏览器上同时运行意味着无论如何抓取都成功,底层有住宅出口和反检测。若要了解更深的反机器人工作流程,请参阅 Scrapling + Scrapeless 指南抓取浏览器产品页面文档 覆盖了完整的 SDK 表面。首先检查原始 HTML,在可以的情况下选择 Cheerio,在必须时选择 Puppeteer,等待内容而不是时钟。


准备构建你的 AI 驱动的数据管道?

加入我们的社区,申请免费的计划,并与构建 Node 抓取工具的开发者连接:Discord · Telegram

app.scrapeless.com 注册,获取免费的抓取浏览器运行时,并将上述模式应用于你的工作流程所需的静态和动态页面。有关规模的信息,请参见 定价


常见问题

问:我什么时候应该使用 Cheerio 而不是 Puppeteer?
当数据已存在于页面的初始 HTML 中。Cheerio 只是解析标记,因此它更快且更简单——无渲染。当 JavaScript 构建内容时使用 Puppeteer。

问:我如何知道一个页面是静态的还是动态的?
查看原始页面源(而不是检查器)。如果数据在源中,它就是静态的——Cheerio 有效。如果源是一个几乎空的外壳且内容仅出现在实时 DOM 中,则它是动态的——使用 Puppeteer。

问:我可以在同一页面上使用两者吗?
是的。使用 Puppeteer 渲染,然后将 page.content() 传递给 Cheerio,如果你更喜欢其对于静态部分的选择器操作。

问:Cheerio vs Playwright vs Puppeteer — 选哪个?
Cheerio 用于静态解析。Puppeteer 或 Playwright(都是完整浏览器)用于动态渲染 —— 选择你的技术栈已使用的那个;Scrapeless 会话可以与两者通过 CDP 一起使用。

问:我需要代理吗?
对于公共静态页面,通常不需要 — 但固定 proxyCountry 会提供一个一致的住宅 IP,真实网站将其视为正常访客,这在扩展时更加重要。

问:我可以不使用 AI 代理运行这个吗?
可以。它是 Scrapeless SDK 加上普通的 Puppeteer 和 Cheerio — 不需要代理。

在Scrapeless,我们仅访问公开可用的数据,并严格遵循适用的法律、法规和网站隐私政策。本博客中的内容仅供演示之用,不涉及任何非法或侵权活动。我们对使用本博客或第三方链接中的信息不做任何保证,并免除所有责任。在进行任何抓取活动之前,请咨询您的法律顾问,并审查目标网站的服务条款或获取必要的许可。

最受欢迎的文章

目录