
Nikolai Smirnov
Software Development Lead
已发表 Jul 09, 2024
已更新 Dec 03, 2025 · 最小阅读量

网络爬虫已成为任何处理网页数据提取的人不可或缺的技能。无论你是开发者、数据科学家还是热衷于从网站上收集信息的爱好者,Puppeteer 都是你可用的最强大工具之一。本完整指南将深入探讨 Puppeteer 是什么,以及如何在网页爬虫中有效使用它。
Puppeteer 是一个 Node 库,它通过 DevTools 协议提供了一种高级 API 来控制 Chrome 或 Chromium。它由 Google Chrome 团队维护,为开发者提供了执行各种浏览器任务的能力,例如生成截图、爬取网站,最重要的是网页爬虫。Puppeteer 因其无头浏览功能而广受欢迎,这意味着它可以在没有图形用户界面的情况下运行,非常适合自动化任务。
领取 CapSolver 奖励代码
立即提升您的自动化预算!
在充值 CapSolver 账户时使用奖励代码 CAPN,每次充值均可获得额外 5% 奖励 —— 没有限制。
立即在您的 CapSolver 仪表板 中领取
.
Axios 和 Cheerio 是 JavaScript 网页爬虫的绝佳选择,但它们存在限制:处理动态内容和绕过反爬虫机制。
作为无头浏览器,Puppeteer 在爬取动态内容方面表现出色。它可以完全加载目标页面,执行 JavaScript,并且甚至可以触发 XHR 请求以获取更多数据。这是静态爬虫无法实现的,尤其是对于单页应用(SPAs)而言,因为初始 HTML 缺乏大量数据。
Puppeteer 还能做什么?它可以渲染图片、捕获截图,并且有扩展程序来解决各种验证码,如 reCAPTCHA、验证码、验证码等。例如,您可以编写脚本以浏览页面、在特定时间间隔捕获截图,并分析这些图片以获得竞争优势洞察。可能性几乎是无限的!
我们之前使用 Selenium 和 Python 完成了 ScrapingClub 的第一部分。现在,让我们使用 Puppeteer 完成第二部分

在开始之前,请确保在本地机器上安装了 Puppeteer。如果没有,请使用以下命令安装:
npm i puppeteer # 安装时会下载兼容的 Chrome
npm i puppeteer-core # 或者作为库安装,不下载 Chrome
const puppeteer = require('puppeteer');
(async function() {
const browser = await puppeteer.launch({headless: false});
const page = await browser.newPage();
await page.goto('https://scrapingclub.com/exercise/detail_json/');
// 暂停 5 秒
await new Promise(r => setTimeout(r, 5000));
await browser.close();
})();
puppeteer.launch 方法用于启动一个新的 Puppeteer 实例,并可以接受一个包含多个选项的配置对象。最常见的选项是 headless,它指定是否以无头模式运行浏览器。如果不指定此参数,它默认为 true。其他常见的配置选项如下:
| 参数 | 类型 | 默认值 | 描述 | 示例 |
|---|---|---|---|---|
args |
string[] |
启动浏览器时传递的命令行参数数组 | args: ['--no-sandbox', '--disable-setuid-sandbox'] |
|
debuggingPort |
number |
指定要使用的调试端口号 | debuggingPort: 8888 |
|
defaultViewport |
dict |
{width: 800, height: 600} |
设置默认视口大小 | defaultViewport: {width: 1920, height: 1080} |
devtools |
boolean |
false |
是否自动打开 DevTools | devtools: true |
executablePath |
string |
指定浏览器可执行文件的路径 | executablePath: '/path/to/chrome' |
|
headless |
boolean 或 'shell' |
true |
是否以无头模式运行浏览器 | headless: false |
userDataDir |
string |
指定用户数据目录的路径 | userDataDir: '/path/to/user/data' |
|
timeout |
number |
30000 |
等待浏览器启动的超时时间(毫秒) | timeout: 60000 |
ignoreHTTPSErrors |
boolean |
false |
是否忽略 HTTPS 错误 | ignoreHTTPSErrors: true |
为了获得最佳浏览体验,我们需要调整两个参数:视口大小和浏览器窗口大小。代码如下:
const puppeteer = require('puppeteer');
(async function() {
const browser = await puppeteer.launch({
headless: false,
args: ['--window-size=1920,1080']
});
const page = await browser.newPage();
await page.setViewport({width: 1920, height: 1080});
await page.goto('https://scrapingclub.com/exercise/detail_json/');
// 暂停 5 秒
await new Promise(r => setTimeout(r, 5000));
await browser.close();
})();
在 Puppeteer 中,有多种方法可以提取数据。
使用 evaluate 方法
evaluate 方法在浏览器上下文中执行 JavaScript 代码以提取所需数据。
const puppeteer = require('puppeteer');
(async function () {
const browser = await puppeteer.launch({
headless: false,
args: ['--window-size=1920,1080']
});
const page = await browser.newPage();
await page.setViewport({width: 1920, height: 1080});
await page.goto('https://scrapingclub.com/exercise/detail_json/');
const data = await page.evaluate(() => {
const image = document.querySelector('.card-img-top').src;
const title = document.querySelector('.card-title').innerText;
const price = document.querySelector('.card-price').innerText;
const description = document.querySelector('.card-description').innerText;
return {image, title, price, description};
});
console.log('产品名称:', data.title);
console.log('产品价格:', data.price);
console.log('产品图片:', data.image);
console.log('产品描述:', data.description);
// 暂停 5 秒
await new Promise(r => setTimeout(r, 5000));
await browser.close();
})();
使用 $eval 方法
$eval 方法选择单个元素并提取其内容。
const puppeteer = require('puppeteer');
(async function () {
const browser = await puppeteer.launch({
headless: false,
args: ['--window-size=1920,1080']
});
const page = await browser.newPage();
await page.setViewport({width: 1920, height: 1080});
await page.goto('https://scrapingclub.com/exercise/detail_json/');
const title = await page.$eval('.card-title', el => el.innerText);
const price = await page.$eval('.card-price', el => el.innerText);
const image = await page.$eval('.card-img-top', el => el.src);
const description = await page.$eval('.card-description', el => el.innerText);
console.log('产品名称:', title);
console.log('产品价格:', price);
console.log('产品图片:', image);
console.log('产品描述:', description);
// 暂停 5 秒
await new Promise(r => setTimeout(r, 5000));
await browser.close();
})();
使用 $$eval 方法
$$eval 方法一次选择多个元素并提取它们的内容。
const puppeteer = require('puppeteer');
(async function () {
const browser = await puppeteer.launch({
headless: false,
args: ['--window-size=1920,1080']
});
const page = await browser.newPage();
await page.setViewport({width: 1920, height: 1080});
await page.goto('https://scrapingclub.com/exercise/detail_json/');
const data = await page.$$eval('.my-8.w-full.rounded.border > *', elements => {
const image = elements[0].querySelector('img').src;
const title = elements[1].querySelector('.card-title').innerText;
const price = elements[1].querySelector('.card-price').innerText;
const description = elements[1].querySelector('.card-description').innerText;
return {image, title, price, description};
});
console.log('产品名称:', data.title);
console.log('产品价格:', data.price);
console.log('产品图片:', data.image);
console.log('产品描述:', data.description);
// 暂停 5 秒
await new Promise(r => setTimeout(r, 5000));
await browser.close();
})();
使用 page.$ 和 evaluate 方法
page.$ 方法选择元素,evaluate 方法在浏览器上下文中执行 JavaScript 代码以提取数据。
const puppeteer = require('puppeteer');
(async function () {
const browser = await puppeteer.launch({
headless: false,
args: ['--window-size=1920,1080']
});
const page = await browser.newPage();
await page.setViewport({width: 1920, height: 1080});
await page.goto('https://scrapingclub.com/exercise/detail_json/');
const imageElement = await page.$('.card-img-top');
const titleElement = await page.$('.card-title');
const priceElement = await page.$('.card-price');
const descriptionElement = await page.$('.card-description');
const image = await page.evaluate(el => el.src, imageElement);
const title = await page.evaluate(el => el.innerText, titleElement);
const price = await page.evaluate(el => el.innerText, priceElement);
const description = await page.evaluate(el => el.innerText, descriptionElement);
console.log('产品名称:', title);
console.log('产品价格:', price);
console.log('产品图片:', image);
console.log('产品描述:', description);
// 暂停 5 秒
await new Promise(r => setTimeout(r, 5000));
await browser.close();
})();
完成 ScrapingClub 的练习相对简单。然而,在实际的数据爬虫场景中,获取数据并不总是那么容易。一些网站采用反爬虫技术,可能会检测到您的脚本为机器人并将其阻止。最常见的场景包括验证码挑战,如 验证码、验证码、reCAPTCHA、验证码和验证码。

要解决这些验证码挑战,需要丰富的机器学习、逆向工程和浏览器指纹识别对策经验,这可能需要大量时间。
幸运的是,您不再需要自己处理所有这些工作。CapSolver 提供了一个全面的解决方案,帮助您轻松解决所有挑战。CapSolver 提供了一个浏览器扩展,允许您在使用 Puppeteer 进行数据爬虫时自动解决验证码挑战。此外,它还提供了一个 API 方法来解决验证码并获取令牌。所有这些操作只需几秒钟即可完成。查看此文档 了解如何解决您遇到的各种验证码问题!
网络爬虫对于任何涉及网页数据提取的人来说都是一项宝贵的技能,而 Puppeteer 作为一个具有高级 API 和强大功能的工具,是实现这一目标的最佳选择之一。它处理动态内容和解决反爬虫机制的能力使其在众多爬虫工具中脱颖而出。
在本指南中,我们探讨了 Puppeteer 是什么,它在网页爬虫中的优势,以及如何设置和有效使用它。我们通过示例展示了如何访问网页、设置视口大小以及使用各种方法提取数据。此外,我们还讨论了反验证码技术带来的挑战以及 CapSolver 如何提供强大的解决方案来应对验证码问题。
Puppeteer 用于控制真实 Chrome/Chromium 浏览器,使其能够加载动态 JavaScript,渲染单页应用(SPA)页面,与元素交互,并提取正常基于 HTTP 的爬虫无法访问的数据。
Puppeteer 单独无法绕过验证码,但当与 CapSolver 的浏览器扩展或 API 结合使用时,可以在爬虫任务中自动解决 reCAPTCHA、hCaptcha、FunCAPTCHA 等验证挑战。
不需要。Puppeteer 支持 无头模式,其中 Chrome 在没有 GUI 的情况下运行。这种模式更快,非常适合自动化。您也可以在非无头模式下运行以进行调试或可视化监控。

Nikolai Smirnov
Software Development Lead
Building dependable software for complex automation.
关于作者